Bash-4.3 distribution sources and documentation

This commit is contained in:
Chet Ramey 2014-02-26 09:36:43 -05:00
commit ac50fbac37
497 changed files with 129395 additions and 87598 deletions

View file

@ -1,6 +1,6 @@
# This Makefile for building libbuiltins.a is in -*- text -*- for Emacs.
#
# Copyright (C) 1996-2009 Free Software Foundation, Inc.
# Copyright (C) 1996-2009 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -67,8 +67,8 @@ LIBS = @LIBS@
LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(CFLAGS)
LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ $(LOCAL_LDFLAGS) $(CFLAGS_FOR_BUILD)
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
#LIBS_FOR_BUILD = @LIBS_FOR_BUILD@
LIBS_FOR_BUILD = $(LIBS)
LIBS_FOR_BUILD = @LIBS_FOR_BUILD@
#LIBS_FOR_BUILD = $(LIBS)
BASHINCDIR = ${topdir}/include
@ -85,6 +85,8 @@ LIBINTL_H = @LIBINTL_H@
HELPDIR = @HELPDIR@
MKDIRS = ${topdir}/support/mkdirs
HELPFILES_TARGET = @HELPFILES_TARGET@
INCLUDES = -I. -I.. @RL_INCLUDE@ -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib -I$(srcdir) ${INTL_INC}
BASE_CCFLAGS = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) \
@ -153,15 +155,33 @@ OFILES = builtins.o \
suspend.o test.o times.o trap.o type.o ulimit.o umask.o \
wait.o getopts.o shopt.o printf.o getopt.o bashgetopt.o complete.o
CREATED_FILES = builtext.h builtins.c psize.aux pipesize.h
CREATED_FILES = builtext.h builtins.c psize.aux pipesize.h tmpbuiltins.c \
tmpbuiltins.h
CREATED_OBJECTS = tmpbuiltins.o gen-helpfiles.o mkbuiltins.o
all: $(MKBUILTINS) libbuiltins.a
all: $(MKBUILTINS) libbuiltins.a $(HELPFILES_TARGET)
targets: libbuiltins.a $(HELPFILES_TARGET)
libbuiltins.a: $(MKBUILTINS) $(OFILES) builtins.o
$(RM) $@
$(AR) $(ARFLAGS) $@ $(OFILES)
-$(RANLIB) $@
tmpbuiltins.c: $(MKBUILTINS) $(DEFSRC)
./$(MKBUILTINS) -externfile tmpbuiltins.h -structfile $@ \
-noproduction -nofunctions \
$(DIRECTDEFINE) $(HELPSTRINGS) $(DEFSRC)
tmpbuiltins.h: tmpbuiltins.c
gen-helpfiles.o: ../config.h
gen-helpfiles.o: gen-helpfiles.c
$(RM) $@
$(CC_FOR_BUILD) -c $(CCFLAGS_FOR_BUILD) $<
gen-helpfiles: tmpbuiltins.o gen-helpfiles.o
$(CC_FOR_BUILD) ${CCFLAGS_FOR_BUILD} $(LDFLAGS_FOR_BUILD) -o $@ gen-helpfiles.o tmpbuiltins.o $(LIBS_FOR_BUILD)
builtext.h builtins.c: $(MKBUILTINS) $(DEFSRC)
@-if test -f builtins.c; then mv -f builtins.c old-builtins.c; fi
@-if test -f builtext.h; then mv -f builtext.h old-builtext.h; fi
@ -178,8 +198,8 @@ builtext.h builtins.c: $(MKBUILTINS) $(DEFSRC)
$(RM) old-builtins.c; \
fi
helpdoc: $(MKBUILTINS) $(DEFSRC)
./$(MKBUILTINS) ${HELPDIRDEFINE} -noproduction $(DIRECTDEFINE) $(DEFSRC)
helpdoc: gen-helpfiles
./gen-helpfiles ${HELPDIRDEFINE}
install-help:
@-if test -n "${HELPDIR}" && test -d helpfiles ; then \
@ -207,15 +227,20 @@ common.o: common.c
bashgetopt.o: bashgetopt.c
getopt.o: getopt.c
evalstring.o: evalstring.c
evalfile.o: evalfile.c
evalfile.o: evalfile.c
tmpbuiltins.o: tmpbuiltins.c
gen-helpfiles.o: gen-helpfiles.c
ulimit.o: pipesize.h
pipesize.h: psize.aux
$(SHELL) $(srcdir)/psize.sh > $@
# Technically this is wrong; the pipe size should be for the target system,
# not the build host.
psize.aux: psize.c
$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(srcdir)/psize.c
$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) ${LDFLAGS_FOR_BUILD} -o $@ $(srcdir)/psize.c
documentation: builtins.texi
@ -223,7 +248,8 @@ builtins.texi: $(MKBUILTINS)
./$(MKBUILTINS) -documentonly $(DEFSRC)
clean:
$(RM) $(OFILES) $(CREATED_FILES) $(MKBUILTINS) mkbuiltins.o libbuiltins.a
$(RM) $(OFILES) $(CREATED_FILES) libbuiltins.a
$(RM) $(MKBUILTINS) gen-helpfiles $(CREATED_OBJECTS)
-test -d helpfiles && $(RM) -r helpfiles
mostlyclean:
@ -547,7 +573,7 @@ shopt.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h
shopt.o: $(topdir)/subst.h $(topdir)/externs.h $(BASHINCDIR)/maxpath.h
shopt.o: $(topdir)/shell.h $(topdir)/syntax.h $(topdir)/unwind_prot.h $(topdir)/variables.h $(topdir)/conftypes.h
shopt.o: $(srcdir)/common.h $(srcdir)/bashgetopt.h ../pathnames.h
shopt.o: $(topdir)/bashhist.h
shopt.o: $(topdir)/bashhist.h $(topdir)/bashline.h
source.o: $(topdir)/command.h ../config.h $(BASHINCDIR)/memalloc.h
source.o: $(topdir)/error.h $(topdir)/general.h $(topdir)/xmalloc.h $(topdir)/findcmd.h
source.o: $(topdir)/quit.h $(topdir)/dispose_cmd.h $(topdir)/make_cmd.h

View file

@ -25,7 +25,7 @@ $PRODUCES bind.c
$BUILTIN bind
$DEPENDS_ON READLINE
$FUNCTION bind_builtin
$SHORT_DOC bind [-lpvsPVS] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command]
$SHORT_DOC bind [-lpsvPSVX] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command]
Set Readline key bindings and variables.
Bind a key sequence to a Readline function or a macro, or set a
@ -54,6 +54,8 @@ Options:
-f filename Read key bindings from FILENAME.
-x keyseq:shell-command Cause SHELL-COMMAND to be executed when
KEYSEQ is entered.
-X List key sequences bound with -x and associated commands
in a form that can be reused as input.
Exit Status:
bind returns 0 unless an unrecognized option is given or an error occurs.
@ -104,6 +106,7 @@ extern int no_line_editing;
#define SSFLAG 0x0400
#define UFLAG 0x0800
#define XFLAG 0x1000
#define XXFLAG 0x2000
int
bind_builtin (list)
@ -138,7 +141,7 @@ bind_builtin (list)
rl_outstream = stdout;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "lvpVPsSf:q:u:m:r:x:")) != EOF)
while ((opt = internal_getopt (list, "lvpVPsSXf:q:u:m:r:x:")) != EOF)
{
switch (opt)
{
@ -187,6 +190,9 @@ bind_builtin (list)
flags |= XFLAG;
cmd_seq = list_optarg;
break;
case 'X':
flags |= XXFLAG;
break;
default:
builtin_usage ();
BIND_RETURN (EX_USAGE);
@ -201,7 +207,7 @@ bind_builtin (list)
if ((flags & MFLAG) && map_name)
{
kmap = rl_get_keymap_by_name (map_name);
if (!kmap)
if (kmap == 0)
{
builtin_error (_("`%s': invalid keymap name"), map_name);
BIND_RETURN (EXECUTION_FAILURE);
@ -265,6 +271,9 @@ bind_builtin (list)
if (flags & XFLAG)
return_code = bind_keyseq_to_unix_command (cmd_seq);
if (flags & XXFLAG)
return_code = print_unix_command_map ();
/* Process the rest of the arguments as binding specifications. */
while (list)
{

View file

@ -2,6 +2,7 @@ This file is caller.def, from which is created caller.c. It implements the
builtin "caller" in Bash.
Copyright (C) 2002-2008 Rocky Bernstein for Free Software Foundation, Inc.
Copyright (C) 2008-2013 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -121,7 +122,7 @@ caller_builtin (list)
{
sh_invalidnum (list->word->word);
builtin_usage ();
return (EXECUTION_FAILURE);
return (EX_USAGE);
}
return (EXECUTION_SUCCESS);

View file

@ -1,7 +1,7 @@
This file is cd.def, from which is created cd.c. It implements the
builtins "cd" and "pwd" in Bash.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
Copyright (C) 1987-2013 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -31,9 +31,10 @@ $PRODUCES cd.c
#include "../bashtypes.h"
#include "posixdir.h"
#include "posixstat.h"
#ifndef _MINIX
#if defined (HAVE_SYS_PARAM_H)
#include <sys/param.h>
#endif
#include <fcntl.h>
#include <stdio.h>
@ -60,7 +61,10 @@ extern const char * const bash_getcwd_errstr;
static int bindpwd __P((int));
static int setpwd __P((char *));
static char *resetpwd __P((char *));
static int change_to_directory __P((char *, int));
static int change_to_directory __P((char *, int, int));
static int cdxattr __P((char *, char **));
static void resetxattr __P((void));
/* Change this to 1 to get cd spelling correction by default. */
int cdspelling = 0;
@ -68,10 +72,12 @@ int cdspelling = 0;
int cdable_vars;
static int eflag; /* file scope so bindpwd() can see it */
static int xattrflag; /* O_XATTR support for openat */
static int xattrfd = -1;
$BUILTIN cd
$FUNCTION cd_builtin
$SHORT_DOC cd [-L|[-P [-e]]] [dir]
$SHORT_DOC cd [-L|[-P [-e]] [-@]] [dir]
Change the shell working directory.
Change the current directory to DIR. The default DIR is the value of the
@ -87,13 +93,21 @@ the word is assumed to be a variable name. If that variable has a value,
its value is used for DIR.
Options:
-L force symbolic links to be followed
-L force symbolic links to be followed: resolve symbolic links in
DIR after processing instances of `..'
-P use the physical directory structure without following symbolic
links
links: resolve symbolic links in DIR before processing instances
of `..'
-e if the -P option is supplied, and the current working directory
cannot be determined successfully, exit with a non-zero status
#if defined (O_XATTR)
-@ on systems that support it, present a file with extended attributes
as a directory containing the file attributes
#endif
The default is to follow symbolic links, as if `-L' were specified.
`..' is processed by removing the immediately previous pathname component
back to a slash or the beginning of DIR.
Exit Status:
Returns 0 if the directory is changed, and if $PWD is set successfully when
@ -173,6 +187,66 @@ resetpwd (caller)
return (tdir);
}
static int
cdxattr (dir, ndirp)
char *dir; /* don't assume we can always free DIR */
char **ndirp; /* return new constructed directory name */
{
#if defined (O_XATTR)
int apfd, fd, r, e;
char buf[11+40+40]; /* construct new `fake' path for pwd */
apfd = openat (AT_FDCWD, dir, O_RDONLY|O_NONBLOCK);
if (apfd < 0)
return -1;
fd = openat (apfd, ".", O_XATTR);
e = errno;
close (apfd); /* ignore close error for now */
errno = e;
if (fd < 0)
return -1;
r = fchdir (fd); /* assume fchdir exists everywhere with O_XATTR */
if (r < 0)
{
close (fd);
return -1;
}
/* NFSv4 and ZFS extended attribute directories do not have names which are
visible in the standard Unix directory tree structure. To ensure we have
a valid name for $PWD, we synthesize one under /proc, but to keep that
path valid, we need to keep the file descriptor open as long as we are in
this directory. This imposes a certain structure on /proc. */
if (ndirp)
{
sprintf (buf, "/proc/%d/fd/%d", getpid(), fd);
*ndirp = savestring (buf);
}
if (xattrfd >= 0)
close (xattrfd);
xattrfd = fd;
return r;
#else
return -1;
#endif
}
/* Clean up the O_XATTR baggage. Currently only closes xattrfd */
static void
resetxattr ()
{
#if defined (O_XATTR)
if (xattrfd >= 0)
{
close (xattrfd);
xattrfd = -1;
}
#else
xattrfd = -1; /* not strictly necessary */
#endif
}
#define LCD_DOVARS 0x001
#define LCD_DOSPELL 0x002
#define LCD_PRINTPATH 0x004
@ -199,8 +273,13 @@ cd_builtin (list)
eflag = 0;
no_symlinks = no_symbolic_links;
xattrflag = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "LP")) != -1)
#if defined (O_XATTR)
while ((opt = internal_getopt (list, "eLP@")) != -1)
#else
while ((opt = internal_getopt (list, "eLP")) != -1)
#endif
{
switch (opt)
{
@ -213,9 +292,14 @@ cd_builtin (list)
case 'e':
eflag = 1;
break;
#if defined (O_XATTR)
case '@':
xattrflag = 1;
break;
#endif
default:
builtin_usage ();
return (EXECUTION_FAILURE);
return (EX_USAGE);
}
}
list = loptend;
@ -237,6 +321,13 @@ cd_builtin (list)
}
lflag = 0;
}
#if defined (CD_COMPLAINS)
else if (list->next)
{
builtin_error (_("too many arguments"));
return (EXECUTION_FAILURE);
}
#endif
else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
{
/* This is `cd -', equivalent to `cd $OLDPWD' */
@ -268,7 +359,7 @@ cd_builtin (list)
temp = sh_makepath (path, dirname, MP_DOTILDE);
free (path);
if (change_to_directory (temp, no_symlinks))
if (change_to_directory (temp, no_symlinks, xattrflag))
{
/* POSIX.2 says that if a nonempty directory from CDPATH
is used to find the directory to change to, the new
@ -290,7 +381,8 @@ cd_builtin (list)
free (temp);
}
#if 0 /* changed for bash-4.2 Posix cd description steps 5-6 */
#if 0
/* changed for bash-4.2 Posix cd description steps 5-6 */
/* POSIX.2 says that if `.' does not appear in $CDPATH, we don't
try the current directory, so we just punt now with an error
message if POSIXLY_CORRECT is non-zero. The check for cdpath[0]
@ -308,7 +400,7 @@ cd_builtin (list)
/* When we get here, DIRNAME is the directory to change to. If we
chdir successfully, just return. */
if (change_to_directory (dirname, no_symlinks))
if (change_to_directory (dirname, no_symlinks, xattrflag))
{
if (lflag & LCD_PRINTPATH)
printf ("%s\n", dirname);
@ -321,7 +413,7 @@ cd_builtin (list)
if (lflag & LCD_DOVARS)
{
temp = get_string_value (dirname);
if (temp && change_to_directory (temp, no_symlinks))
if (temp && change_to_directory (temp, no_symlinks, xattrflag))
{
printf ("%s\n", temp);
return (bindpwd (no_symlinks));
@ -334,9 +426,10 @@ cd_builtin (list)
if (lflag & LCD_DOSPELL)
{
temp = dirspell (dirname);
if (temp && change_to_directory (temp, no_symlinks))
if (temp && change_to_directory (temp, no_symlinks, xattrflag))
{
printf ("%s\n", temp);
free (temp);
return (bindpwd (no_symlinks));
}
else
@ -391,7 +484,7 @@ pwd_builtin (list)
break;
default:
builtin_usage ();
return (EXECUTION_FAILURE);
return (EX_USAGE);
}
}
list = loptend;
@ -405,7 +498,11 @@ pwd_builtin (list)
the file system has changed state underneath bash). */
if ((tcwd && directory == 0) ||
(posixly_correct && same_file (".", tcwd, (struct stat *)0, (struct stat *)0) == 0))
directory = resetpwd ("pwd");
{
if (directory && directory != tcwd)
free (directory);
directory = resetpwd ("pwd");
}
#undef tcwd
@ -431,11 +528,11 @@ pwd_builtin (list)
to the working directory. Return 1 on success, 0 on failure. */
static int
change_to_directory (newdir, nolinks)
change_to_directory (newdir, nolinks, xattr)
char *newdir;
int nolinks;
int nolinks, xattr;
{
char *t, *tdir;
char *t, *tdir, *ndir;
int err, canon_failed, r, ndlen, dlen;
tdir = (char *)NULL;
@ -484,8 +581,34 @@ change_to_directory (newdir, nolinks)
return (0);
}
#if defined (O_XATTR)
if (xattrflag)
{
r = cdxattr (nolinks ? newdir : tdir, &ndir);
if (r >= 0)
{
canon_failed = 0;
free (tdir);
tdir = ndir;
}
else
{
err = errno;
free (tdir);
errno = err;
return (0); /* no xattr */
}
}
else
#endif
{
r = chdir (nolinks ? newdir : tdir);
if (r >= 0)
resetxattr ();
}
/* If the chdir succeeds, update the_current_working_directory. */
if (chdir (nolinks ? newdir : tdir) == 0)
if (r == 0)
{
/* If canonicalization failed, but the chdir succeeded, reset the
shell's idea of the_current_working_directory. */
@ -494,6 +617,8 @@ change_to_directory (newdir, nolinks)
t = resetpwd ("cd");
if (t == 0)
set_working_directory (tdir);
else
free (t);
}
else
set_working_directory (tdir);

View file

@ -500,7 +500,7 @@ get_exitstat (list)
if (arg == 0 || legal_number (arg, &sval) == 0)
{
sh_neednumarg (list->word->word ? list->word->word : "`'");
return 255;
return EX_BADUSAGE;
}
no_args (list->next);
@ -628,7 +628,7 @@ get_job_by_name (name, flags)
if (this_shell_builtin)
builtin_error (_("%s: ambiguous job spec"), name);
else
report_error (_("%s: ambiguous job spec"), name);
internal_error (_("%s: ambiguous job spec"), name);
return (DUP_JOB);
}
else

View file

@ -145,6 +145,8 @@ extern void set_bashopts __P((void));
extern void parse_bashopts __P((char *));
extern void initialize_bashopts __P((int));
extern void set_compatibility_opts __P((void));
/* Functions from type.def */
extern int describe_command __P((char *, int));
@ -153,6 +155,7 @@ extern int set_or_show_attributes __P((WORD_LIST *, int, int));
extern int show_all_var_attributes __P((int, int));
extern int show_var_attributes __P((SHELL_VAR *, int, int));
extern int show_name_attributes __P((char *, int));
extern int show_func_attributes __P((char *, int));
extern void set_var_attribute __P((char *, int, int));
/* Functions from pushd.def */
@ -163,6 +166,7 @@ extern WORD_LIST *get_directory_stack __P((int));
/* Functions from evalstring.c */
extern int parse_and_execute __P((char *, const char *, int));
extern int evalstring __P((char *, const char *, int));
extern void parse_and_execute_cleanup __P((void));
extern int parse_string __P((char *, const char *, int, char **));

View file

@ -1,7 +1,7 @@
This file is complete.def, from which is created complete.c.
It implements the builtins "complete", "compgen", and "compopt" in Bash.
Copyright (C) 1999-2010 Free Software Foundation, Inc.
Copyright (C) 1999-2011 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -112,7 +112,7 @@ static const struct _compacts {
{ "export", CA_EXPORT, 'e' },
{ "file", CA_FILE, 'f' },
{ "function", CA_FUNCTION, 0 },
{ "helptopic", CA_BUILTIN, 0 }, /* for now */
{ "helptopic", CA_HELPTOPIC, 0 },
{ "hostname", CA_HOSTNAME, 0 },
{ "group", CA_GROUP, 'g' },
{ "job", CA_JOB, 'j' },
@ -129,7 +129,7 @@ static const struct _compacts {
};
/* This should be a STRING_INT_ALIST */
const static struct _compopt {
static const struct _compopt {
const char * const optname;
int optflag;
} compopts[] = {
@ -137,6 +137,7 @@ const static struct _compopt {
{ "default", COPT_DEFAULT },
{ "dirnames", COPT_DIRNAMES },
{ "filenames",COPT_FILENAMES},
{ "noquote", COPT_NOQUOTE },
{ "nospace", COPT_NOSPACE },
{ "plusdirs", COPT_PLUSDIRS },
{ (char *)NULL, 0 },
@ -728,6 +729,7 @@ compgen_builtin (list)
if ((sl == 0 || sl->list_len == 0) && (copts & COPT_DEFAULT))
{
matches = rl_completion_matches (word, rl_filename_completion_function);
strlist_dispose (sl);
sl = completions_to_stringlist (matches);
strvec_dispose (matches);
}

View file

@ -1,7 +1,7 @@
This file is declare.def, from which is created declare.c.
It implements the builtins "declare" and "local" in Bash.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
Copyright (C) 1987-2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -22,7 +22,7 @@ $PRODUCES declare.c
$BUILTIN declare
$FUNCTION declare_builtin
$SHORT_DOC declare [-aAfFgilrtux] [-p] [name[=value] ...]
$SHORT_DOC declare [-aAfFgilnrtux] [-p] [name[=value] ...]
Set variable values and attributes.
Declare variables and give them attributes. If no NAMEs are given,
@ -41,6 +41,7 @@ Options which set attributes:
-A to make NAMEs associative arrays (if supported)
-i to make NAMEs have the `integer' attribute
-l to convert NAMEs to lower case on assignment
-n make NAME a reference to the variable named by its value
-r to make NAMEs readonly
-t to make NAMEs have the `trace' attribute
-u to convert NAMEs to upper case on assignment
@ -55,7 +56,8 @@ When used in a function, `declare' makes NAMEs local, as with the `local'
command. The `-g' option suppresses this behavior.
Exit Status:
Returns success unless an invalid option is supplied or an error occurs.
Returns success unless an invalid option is supplied or a variable
assignment error occurs.
$END
$BUILTIN typeset
@ -110,8 +112,8 @@ Local variables can only be used within a function; they are visible
only to the function where they are defined and its children.
Exit Status:
Returns success unless an invalid option is supplied, an error occurs,
or the shell is not executing a function.
Returns success unless an invalid option is supplied, a variable
assignment error occurs, or the shell is not executing a function.
$END
int
local_builtin (list)
@ -127,9 +129,9 @@ local_builtin (list)
}
#if defined (ARRAY_VARS)
# define DECLARE_OPTS "+acfgilprtuxAF"
# define DECLARE_OPTS "+acfgilnprtuxAF"
#else
# define DECLARE_OPTS "+cfgilprtuxF"
# define DECLARE_OPTS "+cfgilnprtuxF"
#endif
/* The workhorse function. */
@ -139,12 +141,13 @@ declare_internal (list, local_var)
int local_var;
{
int flags_on, flags_off, *flags;
int any_failed, assign_error, pflag, nodefs, opt, mkglobal;
int any_failed, assign_error, pflag, nodefs, opt, mkglobal, onref, offref;
char *t, *subscript_start;
SHELL_VAR *var;
SHELL_VAR *var, *refvar, *v;
FUNCTION_DEF *shell_fn;
flags_on = flags_off = any_failed = assign_error = pflag = nodefs = mkglobal = 0;
refvar = (SHELL_VAR *)NULL;
reset_internal_getopt ();
while ((opt = internal_getopt (list, DECLARE_OPTS)) != EOF)
{
@ -186,6 +189,9 @@ declare_internal (list, local_var)
case 'i':
*flags |= att_integer;
break;
case 'n':
*flags |= att_nameref;
break;
case 'r':
*flags |= att_readonly;
break;
@ -258,7 +264,10 @@ declare_internal (list, local_var)
{
for (any_failed = 0; list; list = list->next)
{
pflag = show_name_attributes (list->word->word, nodefs);
if (flags_on & att_function)
pflag = show_func_attributes (list->word->word, nodefs);
else
pflag = show_name_attributes (list->word->word, nodefs);
if (pflag)
{
sh_notfound (list->word->word);
@ -296,6 +305,28 @@ declare_internal (list, local_var)
else
value = "";
/* Do some lexical error checking on the LHS and RHS of the assignment
that is specific to nameref variables. */
if (flags_on & att_nameref)
{
#if defined (ARRAY_VARIABLES)
if (valid_array_reference (name))
{
builtin_error (_("%s: reference variable cannot be an array"), name);
assign_error++;
NEXT_VARIABLE ();
}
else
#endif
/* disallow self references at global scope */
if (STREQ (name, value) && variable_context == 0)
{
builtin_error (_("%s: nameref variable self references not allowed"), name);
assign_error++;
NEXT_VARIABLE ();
}
}
#if defined (ARRAY_VARS)
compound_array_assign = simple_array_assign = 0;
subscript_start = (char *)NULL;
@ -334,16 +365,17 @@ declare_internal (list, local_var)
/* XXX - this has consequences when we're making a local copy of a
variable that was in the temporary environment. Watch out
for this. */
refvar = (SHELL_VAR *)NULL;
if (variable_context && mkglobal == 0 && ((flags_on & att_function) == 0))
{
#if defined (ARRAY_VARS)
if (flags_on & att_assoc)
var = make_local_assoc_variable (name);
else if ((flags_on & att_array) || making_array_special)
var = make_local_array_variable (name);
var = make_local_array_variable (name, making_array_special);
else
#endif
var = make_local_variable (name);
var = make_local_variable (name); /* sets att_invisible for new vars */
if (var == 0)
{
any_failed++;
@ -415,6 +447,33 @@ declare_internal (list, local_var)
else /* declare -[aAirx] name [name...] */
{
/* Non-null if we just created or fetched a local variable. */
/* Here's what ksh93 seems to do. If we are modifying an existing
nameref variable, we don't follow the nameref chain past the last
nameref, and we set the nameref variable's value so future
references to that variable will return the value of the variable
we're assigning right now. */
if (var == 0 && (flags_on & att_nameref))
{
/* See if we are trying to modify an existing nameref variable */
var = mkglobal ? find_global_variable_last_nameref (name) : find_variable_last_nameref (name);
if (var && nameref_p (var) == 0)
var = 0;
}
/* However, if we're turning off the nameref attribute on an existing
nameref variable, we first follow the nameref chain to the end,
modify the value of the variable this nameref variable references,
*CHANGING ITS VALUE AS A SIDE EFFECT* then turn off the nameref
flag *LEAVING THE NAMEREF VARIABLE'S VALUE UNCHANGED* */
else if (var == 0 && (flags_off & att_nameref))
{
/* See if we are trying to modify an existing nameref variable */
refvar = mkglobal ? find_global_variable_last_nameref (name) : find_variable_last_nameref (name);
if (refvar && nameref_p (refvar) == 0)
refvar = 0;
if (refvar)
var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar));
}
if (var == 0)
var = mkglobal ? find_global_variable (name) : find_variable (name);
@ -422,20 +481,40 @@ declare_internal (list, local_var)
{
#if defined (ARRAY_VARS)
if (flags_on & att_assoc)
var = make_new_assoc_variable (name);
{
var = make_new_assoc_variable (name);
if (offset == 0)
VSETATTR (var, att_invisible);
}
else if ((flags_on & att_array) || making_array_special)
var = make_new_array_variable (name);
{
var = make_new_array_variable (name);
if (offset == 0)
VSETATTR (var, att_invisible);
}
else
#endif
if (offset)
var = bind_variable (name, "", 0);
var = mkglobal ? bind_global_variable (name, "", 0) : bind_variable (name, "", 0);
else
{
var = bind_variable (name, (char *)NULL, 0);
var = mkglobal ? bind_global_variable (name, (char *)NULL, 0) : bind_variable (name, (char *)NULL, 0);
VSETATTR (var, att_invisible);
}
}
/* Can't take an existing array variable and make it a nameref */
else if ((array_p (var) || assoc_p (var)) && (flags_on & att_nameref))
{
builtin_error (_("%s: reference variable cannot be an array"), name);
assign_error++;
NEXT_VARIABLE ();
}
else if (flags_on & att_nameref)
{
/* ksh93 compat: turning on nameref attribute turns off -ilu */
VUNSETATTR (var, att_integer|att_uppercase|att_lowercase|att_capcase);
}
/* Cannot use declare +r to turn off readonly attribute. */
if (readonly_p (var) && (flags_off & att_readonly))
@ -501,6 +580,25 @@ declare_internal (list, local_var)
var = convert_var_to_array (var);
#endif /* ARRAY_VARS */
/* XXX - we note that we are turning on nameref attribute and defer
setting it until the assignment has been made so we don't do an
inadvertent nameref lookup. Might have to do the same thing for
flags_off&att_nameref. */
/* XXX - ksh93 makes it an error to set a readonly nameref variable
using a single typeset command. */
onref = (flags_on & att_nameref);
flags_on &= ~att_nameref;
#if defined (ARRAY_VARS)
if (array_p (var) || assoc_p (var)
|| (offset && compound_array_assign)
|| simple_array_assign)
onref = 0; /* array variables may not be namerefs */
#endif
/* ksh93 seems to do this */
offref = (flags_off & att_nameref);
flags_off &= ~att_nameref;
VSETATTR (var, flags_on);
VUNSETATTR (var, flags_off);
@ -516,6 +614,8 @@ declare_internal (list, local_var)
if (var == 0) /* some kind of assignment error */
{
assign_error++;
flags_on |= onref;
flags_off |= offref;
NEXT_VARIABLE ();
}
}
@ -532,7 +632,19 @@ declare_internal (list, local_var)
/* bind_variable_value duplicates the essential internals of
bind_variable() */
if (offset)
bind_variable_value (var, value, aflags);
{
if (onref)
aflags |= ASS_NAMEREF;
v = bind_variable_value (var, value, aflags);
if (v == 0 && onref)
{
sh_invalidid (value);
assign_error++;
/* XXX - unset this variable? or leave it as normal var? */
delete_var (var->name, mkglobal ? global_variables : shell_variables);
NEXT_VARIABLE ();
}
}
/* If we found this variable in the temporary environment, as with
`var=value declare -x var', make sure it is treated identically
@ -562,6 +674,17 @@ declare_internal (list, local_var)
}
}
/* Turn on nameref attribute we deferred above. */
/* XXX - should we turn on the noassign attribute for consistency with
ksh93 when we turn on the nameref attribute? */
VSETATTR (var, onref);
flags_on |= onref;
VUNSETATTR (var, offref);
flags_off |= offref;
/* Yuck. ksh93 compatibility */
if (refvar)
VUNSETATTR (refvar, flags_off);
stupidly_hack_special_variables (name);
NEXT_VARIABLE ();

View file

@ -38,7 +38,8 @@ $DEPENDS_ON V9_ECHO
$SHORT_DOC echo [-neE] [arg ...]
Write arguments to the standard output.
Display the ARGs on the standard output followed by a newline.
Display the ARGs, separated by a single space character and followed by a
newline, on the standard output.
Options:
-n do not append a newline
@ -50,6 +51,7 @@ Options:
\b backspace
\c suppress further output
\e escape character
\E escape character
\f form feed
\n new line
\r carriage return

View file

@ -53,6 +53,5 @@ eval_builtin (list)
return (EX_USAGE);
list = loptend; /* skip over possible `--' */
/* Note that parse_and_execute () frees the string it is passed. */
return (list ? parse_and_execute (string_list (list), "eval", SEVAL_NOHIST) : EXECUTION_SUCCESS);
return (list ? evalstring (string_list (list), "eval", SEVAL_NOHIST) : EXECUTION_SUCCESS);
}

View file

@ -109,11 +109,16 @@ _evalfile (filename, flags)
GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a);
# endif
#endif
fd = open (filename, O_RDONLY);
if (fd < 0 || (fstat (fd, &finfo) == -1))
{
i = errno;
if (fd >= 0)
close (fd);
errno = i;
file_error_and_exit:
if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT)
file_error (filename);
@ -133,11 +138,13 @@ file_error_and_exit:
if (S_ISDIR (finfo.st_mode))
{
(*errfunc) (_("%s: is a directory"), filename);
close (fd);
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
}
else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0)
{
(*errfunc) (_("%s: not a regular file"), filename);
close (fd);
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
}
@ -146,6 +153,7 @@ file_error_and_exit:
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
(*errfunc) (_("%s: file is too large"), filename);
close (fd);
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
}
@ -251,7 +259,7 @@ file_error_and_exit:
if (flags & FEVAL_BUILTIN)
result = EXECUTION_SUCCESS;
return_val = setjmp (return_catch);
return_val = setjmp_nosigs (return_catch);
/* If `return' was seen outside of a function, but in the script, then
force parse_and_execute () to clean up. */

View file

@ -1,6 +1,6 @@
/* evalstring.c - evaluate a string as one or more shell commands. */
/* Copyright (C) 1996-2010 Free Software Foundation, Inc.
/* Copyright (C) 1996-2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -61,7 +61,7 @@ extern int errno;
#define IS_BUILTIN(s) (builtin_address_internal(s, 0) != (struct builtin *)NULL)
extern int indirection_level, subshell_environment;
extern int line_number;
extern int line_number, line_number_for_err_trap;
extern int current_token, shell_eof_token;
extern int last_command_exit_value;
extern int running_trap;
@ -69,7 +69,9 @@ extern int loop_level;
extern int executing_list;
extern int comsub_ignore_return;
extern int posixly_correct;
extern int return_catch_flag, return_catch_value;
extern sh_builtin_func_t *this_shell_builtin;
extern char *the_printed_command_except_trap;
int parse_and_execute_level = 0;
@ -86,6 +88,14 @@ set_history_remembering ()
}
#endif
static void
restore_lastcom (x)
char *x;
{
FREE (the_printed_command_except_trap);
the_printed_command_except_trap = x;
}
/* How to force parse_and_execute () to clean up after itself. */
void
parse_and_execute_cleanup ()
@ -108,7 +118,7 @@ parse_prologue (string, flags, tag)
int flags;
char *tag;
{
char *orig_string;
char *orig_string, *lastcom;
int x;
orig_string = string;
@ -118,6 +128,7 @@ parse_prologue (string, flags, tag)
unwind_protect_jmp_buf (top_level);
unwind_protect_int (indirection_level);
unwind_protect_int (line_number);
unwind_protect_int (line_number_for_err_trap);
unwind_protect_int (loop_level);
unwind_protect_int (executing_list);
unwind_protect_int (comsub_ignore_return);
@ -140,8 +151,17 @@ parse_prologue (string, flags, tag)
x = get_current_prompt_level ();
add_unwind_protect (set_current_prompt_level, x);
}
if (the_printed_command_except_trap)
{
lastcom = savestring (the_printed_command_except_trap);
add_unwind_protect (restore_lastcom, lastcom);
}
add_unwind_protect (pop_stream, (char *)NULL);
if (parser_expanding_alias ())
add_unwind_protect (parser_restore_alias, (char *)NULL);
if (orig_string && ((flags & SEVAL_NOFREE) == 0))
add_unwind_protect (xfree, orig_string);
end_unwind_frame ();
@ -175,6 +195,7 @@ parse_and_execute (string, from_file, flags)
int code, lreset;
volatile int should_jump_to_top_level, last_result;
COMMAND *volatile command;
volatile sigset_t pe_sigmask;
parse_prologue (string, flags, PE_TAG);
@ -182,11 +203,21 @@ parse_and_execute (string, from_file, flags)
lreset = flags & SEVAL_RESETLINE;
#if defined (HAVE_POSIX_SIGNALS)
/* If we longjmp and are going to go on, use this to restore signal mask */
sigemptyset (&pe_sigmask);
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &pe_sigmask);
#endif
/* Reset the line number if the caller wants us to. If we don't reset the
line number, we have to subtract one, because we will add one just
before executing the next command (resetting the line number sets it to
0; the first line number is 1). */
push_stream (lreset);
if (parser_expanding_alias ())
/* push current shell_input_line */
parser_save_alias ();
if (lreset == 0)
line_number--;
@ -209,15 +240,28 @@ parse_and_execute (string, from_file, flags)
/* Provide a location for functions which `longjmp (top_level)' to
jump to. This prevents errors in substitution from restarting
the reader loop directly, for example. */
code = setjmp (top_level);
code = setjmp_nosigs (top_level);
if (code)
{
should_jump_to_top_level = 0;
switch (code)
{
case FORCE_EOF:
case ERREXIT:
/* variable_context -> 0 is what eval.c:reader_loop() does in
these circumstances. Don't bother with cleanup here because
we don't want to run the function execution cleanup stuff
that will cause pop_context and other functions to run.
XXX - change that if we want the function context to be
unwound. */
if (exit_immediately_on_error && variable_context)
{
discard_unwind_frame ("pe_dispose");
variable_context = 0; /* not in a function */
}
should_jump_to_top_level = 1;
goto out;
case FORCE_EOF:
case EXITPROG:
if (command)
run_unwind_frame ("pe_dispose");
@ -239,6 +283,9 @@ parse_and_execute (string, from_file, flags)
{
#if 0
dispose_command (command); /* pe_dispose does this */
#endif
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &pe_sigmask, (sigset_t *)NULL);
#endif
continue;
}
@ -308,7 +355,8 @@ parse_and_execute (string, from_file, flags)
command->value.Simple->words == 0 &&
command->value.Simple->redirects &&
command->value.Simple->redirects->next == 0 &&
command->value.Simple->redirects->instruction == r_input_direction)
command->value.Simple->redirects->instruction == r_input_direction &&
command->value.Simple->redirects->redirector.dest == 0)
{
int r;
r = cat_file (command->value.Simple->redirects);
@ -317,7 +365,6 @@ parse_and_execute (string, from_file, flags)
else
last_result = execute_command_internal
(command, 0, NO_PIPE, NO_PIPE, bitmap);
dispose_command (command);
dispose_fd_bitmap (bitmap);
discard_unwind_frame ("pe_dispose");
@ -377,15 +424,26 @@ parse_string (string, from_file, flags, endp)
volatile int should_jump_to_top_level;
COMMAND *volatile command, *oglobal;
char *ostring;
volatile sigset_t ps_sigmask;
parse_prologue (string, flags, PS_TAG);
#if defined (HAVE_POSIX_SIGNALS)
/* If we longjmp and are going to go on, use this to restore signal mask */
sigemptyset (&ps_sigmask);
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &ps_sigmask);
#endif
/* itrace("parse_string: `%s'", string); */
/* Reset the line number if the caller wants us to. If we don't reset the
line number, we have to subtract one, because we will add one just
before executing the next command (resetting the line number sets it to
0; the first line number is 1). */
push_stream (0);
if (parser_expanding_alias ())
/* push current shell_input_line */
parser_save_alias ();
code = should_jump_to_top_level = 0;
oglobal = global_command;
ostring = string;
@ -402,7 +460,7 @@ parse_string (string, from_file, flags, endp)
/* Provide a location for functions which `longjmp (top_level)' to
jump to. */
code = setjmp (top_level);
code = setjmp_nosigs (top_level);
if (code)
{
@ -424,6 +482,9 @@ itrace("parse_string: longjmp executed: code = %d", code);
goto out;
default:
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &ps_sigmask, (sigset_t *)NULL);
#endif
command_error ("parse_string", CMDERR_BADJUMP, code, 0);
break;
}
@ -506,3 +567,49 @@ cat_file (r)
return (rval);
}
int
evalstring (string, from_file, flags)
char *string;
const char *from_file;
int flags;
{
volatile int r, rflag, rcatch;
rcatch = 0;
rflag = return_catch_flag;
/* If we are in a place where `return' is valid, we have to catch
`eval "... return"' and make sure parse_and_execute cleans up. Then
we can trampoline to the previous saved return_catch location. */
if (rflag)
{
begin_unwind_frame ("evalstring");
unwind_protect_int (return_catch_flag);
unwind_protect_jmp_buf (return_catch);
return_catch_flag++; /* increment so we have a counter */
rcatch = setjmp_nosigs (return_catch);
}
if (rcatch)
{
parse_and_execute_cleanup ();
r = return_catch_value;
}
else
/* Note that parse_and_execute () frees the string it is passed. */
r = parse_and_execute (string, from_file, flags);
if (rflag)
{
run_unwind_frame ("evalstring");
if (rcatch && return_catch_flag)
{
return_catch_value = r;
longjmp (return_catch, 1);
}
}
return (r);
}

View file

@ -1,7 +1,7 @@
This file is exec.def, from which is created exec.c.
It implements the builtin "exec" in Bash.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
Copyright (C) 1987-2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -144,7 +144,7 @@ exec_builtin (list)
args = strvec_from_word_list (list, 1, 0, (int *)NULL);
/* A command with a slash anywhere in its name is not looked up in $PATH. */
command = absolute_program (args[0]) ? args[0] : search_for_command (args[0]);
command = absolute_program (args[0]) ? args[0] : search_for_command (args[0], 1);
if (command == 0)
{

View file

@ -1,7 +1,7 @@
This file is fc.def, from which is created fc.c.
It implements the builtin "fc" in Bash.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
Copyright (C) 1987-2011 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -52,7 +52,7 @@ $END
#include <config.h>
#if defined (HISTORY)
#ifndef _MINIX
#if defined (HAVE_SYS_PARAM_H)
# include <sys/param.h>
#endif
#include "../bashtypes.h"
@ -85,7 +85,7 @@ $END
extern int errno;
#endif /* !errno */
extern int current_command_line_count, saved_command_line_count;
extern int current_command_line_count;
extern int literal_history;
extern int posixly_correct;
extern int subshell_environment, interactive_shell;
@ -173,7 +173,7 @@ fc_builtin (list)
register int i;
register char *sep;
int numbering, reverse, listing, execute;
int histbeg, histend, last_hist, retval, opt, rh;
int histbeg, histend, last_hist, retval, opt, rh, real_last;
FILE *stream;
REPL *rlist, *rl;
char *ename, *command, *newcom, *fcedit;
@ -303,6 +303,14 @@ fc_builtin (list)
rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list);
last_hist = i - rh - hist_last_line_added;
/* Make sure that real_last is calculated the same way here and in
fc_gethnum. The return value from fc_gethnum is treated specially if
it is == real_last and we are listing commands. */
real_last = i;
/* back up from the end to the last non-null history entry */
while (hlist[real_last] == 0 && real_last > 0)
real_last--;
/* XXX */
if (i == last_hist && hlist[last_hist] == 0)
while (last_hist >= 0 && hlist[last_hist] == 0)
@ -320,6 +328,8 @@ fc_builtin (list)
if (list)
histend = fc_gethnum (list->word->word, hlist);
else if (histbeg == real_last)
histend = listing ? real_last : histbeg;
else
histend = listing ? last_hist : histbeg;
}
@ -475,7 +485,7 @@ fc_gethnum (command, hlist)
HIST_ENTRY **hlist;
{
int sign, n, clen, rh;
register int i, j, last_hist;
register int i, j, last_hist, real_last;
register char *s;
sign = 1;
@ -503,12 +513,17 @@ fc_gethnum (command, hlist)
if (last_hist < 0)
return (-1);
real_last = i;
i = last_hist;
/* No specification defaults to most recent command. */
if (command == NULL)
return (i);
/* back up from the end to the last non-null history entry */
while (hlist[real_last] == 0 && real_last > 0)
real_last--;
/* Otherwise, there is a specification. It can be a number relative to
the current position, or an absolute history number. */
s = command;
@ -533,7 +548,7 @@ fc_gethnum (command, hlist)
return (n < 0 ? 0 : n);
}
else if (n == 0)
return (i);
return ((sign == -1) ? real_last : i);
else
{
n -= history_base;

197
builtins/gen-helpfiles.c Normal file
View file

@ -0,0 +1,197 @@
/* gen-helpfiles - create files containing builtin help text */
/* Copyright (C) 2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
/* This links with a specially-generated version of builtins.c and takes
the long_doc members of each struct builtin element and writes those to
the file named by the `handle' member of the struct builtin element. */
#if !defined (CROSS_COMPILING)
# include <config.h>
#else /* CROSS_COMPILING */
/* A conservative set of defines based on POSIX/SUS3/XPG6 */
# define HAVE_UNISTD_H
# define HAVE_STRING_H
# define HAVE_STDLIB_H
# define HAVE_RENAME
#endif /* CROSS_COMPILING */
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#ifndef _MINIX
# include "../bashtypes.h"
# if defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
# endif
#endif
#include "posixstat.h"
#include "filecntl.h"
#include "../bashansi.h"
#include <stdio.h>
#include <errno.h>
#include "stdc.h"
#include "../builtins.h"
#include "tmpbuiltins.h"
#if defined (USING_BASH_MALLOC)
#undef xmalloc
#undef xrealloc
#undef xfree
#undef free /* defined in xmalloc.h */
#endif
#ifndef errno
extern int errno;
#endif
#if !defined (__STDC__) && !defined (strcpy)
extern char *strcpy ();
#endif /* !__STDC__ && !strcpy */
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
/* Flag values that builtins can have. */
#define BUILTIN_FLAG_SPECIAL 0x01
#define BUILTIN_FLAG_ASSIGNMENT 0x02
#define BUILTIN_FLAG_POSIX_BUILTIN 0x04
#define BASE_INDENT 4
/* Non-zero means to produce separate help files for each builtin, named by
the builtin name, in `./helpfiles'. */
int separate_helpfiles = 0;
/* Non-zero means to create single C strings for each `longdoc', with
embedded newlines, for ease of translation. */
int single_longdoc_strings = 1;
/* The name of a directory into which the separate external help files will
eventually be installed. */
char *helpfile_directory;
/* Forward declarations. */
int write_helpfiles __P((struct builtin *));
/* For each file mentioned on the command line, process it and
write the information to STRUCTFILE and EXTERNFILE, while
creating the production file if neccessary. */
int
main (argc, argv)
int argc;
char **argv;
{
int arg_index = 1;
while (arg_index < argc && argv[arg_index][0] == '-')
{
char *arg = argv[arg_index++];
if (strcmp (arg, "-noproduction") == 0)
;
else if (strcmp (arg, "-H") == 0)
helpfile_directory = argv[arg_index++];
else if (strcmp (arg, "-S") == 0)
single_longdoc_strings = 0;
else
{
fprintf (stderr, "%s: Unknown flag %s.\n", argv[0], arg);
exit (2);
}
}
write_helpfiles(shell_builtins);
exit (0);
}
/* Write DOCUMENTATION to STREAM, perhaps surrounding it with double-quotes
and quoting special characters in the string. Handle special things for
internationalization (gettext) and the single-string vs. multiple-strings
issues. */
void
write_documentation (stream, documentation, indentation)
FILE *stream;
char *documentation;
int indentation;
{
if (stream == 0)
return;
if (documentation)
fprintf (stream, "%*s%s\n", indentation, " ", documentation);
}
int
write_helpfiles (builtins)
struct builtin *builtins;
{
char *helpfile, *bname, *fname;
FILE *helpfp;
int i, hdlen;
struct builtin b;
i = mkdir ("helpfiles", 0777);
if (i < 0 && errno != EEXIST)
{
fprintf (stderr, "write_helpfiles: helpfiles: cannot create directory\n");
return -1;
}
hdlen = strlen ("helpfiles/");
for (i = 0; i < num_shell_builtins; i++)
{
b = builtins[i];
fname = (char *)b.handle;
helpfile = (char *)malloc (hdlen + strlen (fname) + 1);
if (helpfile == 0)
{
fprintf (stderr, "gen-helpfiles: cannot allocate memory\n");
exit (1);
}
sprintf (helpfile, "helpfiles/%s", fname);
helpfp = fopen (helpfile, "w");
if (helpfp == 0)
{
fprintf (stderr, "write_helpfiles: cannot open %s\n", helpfile);
free (helpfile);
continue;
}
write_documentation (helpfp, b.long_doc[0], 4);
fflush (helpfp);
fclose (helpfp);
free (helpfile);
}
return 0;
}

View file

@ -1,7 +1,7 @@
This file is hash.def, from which is created hash.c.
It implements the builtin "hash" in Bash.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
Copyright (C) 1987-2013 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -31,7 +31,7 @@ no arguments are given, information about remembered commands is displayed.
Options:
-d forget the remembered location of each NAME
-l display in a format that may be reused as input
-p pathname use PATHNAME is the full pathname of NAME
-p pathname use PATHNAME as the full pathname of NAME
-r forget all remembered locations
-t print the remembered location of each NAME, preceding
each location with the corresponding NAME if multiple
@ -276,6 +276,7 @@ list_hashed_filename_targets (list, fmt)
printf ("%s\t", l->word->word);
printf ("%s\n", target);
}
free (target);
}
return (all_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);

View file

@ -1,7 +1,7 @@
This file is help.def, from which is created help.c.
It implements the builtin "help" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2013 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -92,7 +92,7 @@ help_builtin (list)
{
register int i;
char *pattern, *name;
int plen, match_found, sflag, dflag, mflag;
int plen, match_found, sflag, dflag, mflag, m, pass, this_found;
dflag = sflag = mflag = 0;
reset_internal_getopt ();
@ -137,29 +137,43 @@ help_builtin (list)
pattern = list->word->word;
plen = strlen (pattern);
for (i = 0; name = shell_builtins[i].name; i++)
for (pass = 1, this_found = 0; pass < 3; pass++)
{
QUIT;
if ((strncmp (pattern, name, plen) == 0) ||
(strmatch (pattern, name, FNMATCH_EXTFLAG) != FNM_NOMATCH))
for (i = 0; name = shell_builtins[i].name; i++)
{
match_found++;
if (dflag)
{
show_desc (name, i);
continue;
}
else if (mflag)
{
show_manpage (name, i);
continue;
}
QUIT;
printf ("%s: %s\n", name, _(shell_builtins[i].short_doc));
/* First pass: look for exact string or pattern matches.
Second pass: look for prefix matches like bash-4.2 */
if (pass == 1)
m = (strcmp (pattern, name) == 0) ||
(strmatch (pattern, name, FNMATCH_EXTFLAG) != FNM_NOMATCH);
else
m = strncmp (pattern, name, plen) == 0;
if (sflag == 0)
show_longdoc (i);
if (m)
{
this_found = 1;
match_found++;
if (dflag)
{
show_desc (name, i);
continue;
}
else if (mflag)
{
show_manpage (name, i);
continue;
}
printf ("%s: %s\n", name, _(shell_builtins[i].short_doc));
if (sflag == 0)
show_longdoc (i);
}
}
if (pass == 1 && this_found == 1)
break;
}
}
@ -209,7 +223,7 @@ show_longdoc (i)
zcatfd (fd, 1, doc[0]);
close (fd);
}
else
else if (doc)
for (j = 0; doc[j]; j++)
printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j]));
}
@ -326,6 +340,140 @@ show_manpage (name, i)
free (line);
}
static void
dispcolumn (i, buf, bufsize, width, height)
int i;
char *buf;
size_t bufsize;
int width, height;
{
int j;
int displen;
char *helpdoc;
/* first column */
helpdoc = _(shell_builtins[i].short_doc);
buf[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*';
strncpy (buf + 1, helpdoc, width - 2);
buf[width - 2] = '>'; /* indicate truncation */
buf[width - 1] = '\0';
printf ("%s", buf);
if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins))
{
printf ("\n");
return;
}
displen = strlen (buf);
/* two spaces */
for (j = displen; j < width; j++)
putc (' ', stdout);
/* second column */
helpdoc = _(shell_builtins[i+height].short_doc);
buf[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*';
strncpy (buf + 1, helpdoc, width - 3);
buf[width - 3] = '>'; /* indicate truncation */
buf[width - 2] = '\0';
printf ("%s\n", buf);
}
#if defined (HANDLE_MULTIBYTE)
static void
wdispcolumn (i, buf, bufsize, width, height)
int i;
char *buf;
size_t bufsize;
int width, height;
{
int j;
int displen;
char *helpdoc;
wchar_t *wcstr;
size_t slen, n;
int wclen;
/* first column */
helpdoc = _(shell_builtins[i].short_doc);
wcstr = 0;
slen = mbstowcs ((wchar_t *)0, helpdoc, 0);
if (slen == -1)
{
dispcolumn (i, buf, bufsize, width, height);
return;
}
/* No bigger than the passed max width */
if (slen >= width)
slen = width - 2;
wcstr = (wchar_t *)xmalloc (sizeof (wchar_t) * (width + 2));
n = mbstowcs (wcstr+1, helpdoc, slen + 1);
wcstr[n+1] = L'\0';
/* Turn tabs and newlines into spaces for column display, since wcwidth
returns -1 for them */
for (j = 1; j < n; j++)
if (wcstr[j] == L'\n' || wcstr[j] == L'\t')
wcstr[j] = L' ';
displen = wcsnwidth (wcstr+1, slen, width - 2) + 1; /* +1 for ' ' or '*' */
wcstr[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? L' ' : L'*';
/* This assumes each wide char takes up one column position when displayed */
wcstr[width - 2] = L'>'; /* indicate truncation */
wcstr[width - 1] = L'\0';
printf ("%ls", wcstr);
if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins))
{
printf ("\n");
return;
}
/* at least one space */
for (j = displen; j < width; j++)
putc (' ', stdout);
/* second column */
helpdoc = _(shell_builtins[i+height].short_doc);
slen = mbstowcs ((wchar_t *)0, helpdoc, 0);
if (slen == -1)
{
/* for now */
printf ("%c%s\n", (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*', helpdoc);
return;
}
/* Reuse wcstr since it is already width wide chars long */
if (slen >= width)
slen = width - 2;
n = mbstowcs (wcstr+1, helpdoc, slen + 1);
wcstr[n+1] = L'\0'; /* make sure null-terminated */
/* Turn tabs and newlines into spaces for column display */
for (j = 1; j < n; j++)
if (wcstr[j] == L'\n' || wcstr[j] == L'\t')
wcstr[j] = L' ';
displen = wcsnwidth (wcstr+1, slen, width - 2);
wcstr[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? L' ' : L'*';
/* This assumes each wide char takes up one column position when displayed */
wcstr[width - 3] = L'>'; /* indicate truncation */
wcstr[width - 2] = L'\0';
printf ("%ls\n", wcstr);
free (wcstr);
}
#endif /* HANDLE_MULTIBYTE */
static void
show_builtin_command_help ()
{
@ -358,28 +506,12 @@ A star (*) next to a name means that the command is disabled.\n\
{
QUIT;
/* first column */
blurb[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*';
strncpy (blurb + 1, _(shell_builtins[i].short_doc), width - 2);
blurb[width - 2] = '>'; /* indicate truncation */
blurb[width - 1] = '\0';
printf ("%s", blurb);
if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins))
{
printf ("\n");
break;
}
/* two spaces */
for (j = strlen (blurb); j < width; j++)
putc (' ', stdout);
/* second column */
blurb[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*';
strncpy (blurb + 1, _(shell_builtins[i+height].short_doc), width - 3);
blurb[width - 3] = '>'; /* indicate truncation */
blurb[width - 2] = '\0';
printf ("%s\n", blurb);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1)
wdispcolumn (i, blurb, sizeof (blurb), width, height);
else
#endif
dispcolumn (i, blurb, sizeof (blurb), width, height);
}
}
#endif /* HELP_BUILTIN */

View file

@ -324,9 +324,10 @@ push_history (list)
If you don't want history -s to remove the compound command from the
history, change #if 0 to #if 1 below. */
#if 0
if (hist_last_line_pushed == 0 && hist_last_line_added && bash_delete_last_history () == 0)
if (remember_on_history && hist_last_line_pushed == 0 &&
hist_last_line_added && bash_delete_last_history () == 0)
#else
if (hist_last_line_pushed == 0 &&
if (remember_on_history && hist_last_line_pushed == 0 &&
(hist_last_line_added ||
(current_command_line_count > 0 && current_command_first_line_saved && command_oriented_history))
&& bash_delete_last_history () == 0)

View file

@ -31,7 +31,7 @@ Without options, the status of all active jobs is displayed.
Options:
-l lists process IDs in addition to the normal information
-n list only processes that have changed status since the last
-n lists only processes that have changed status since the last
notification
-p lists process IDs only
-r restrict output to running jobs

View file

@ -57,6 +57,8 @@ $END
#include "../bashansi.h"
#include "../bashintl.h"
#include <signal.h>
#include "../shell.h"
#include "../trap.h"
#include "../jobs.h"
@ -92,7 +94,7 @@ kill_builtin (list)
if (list == 0)
{
builtin_usage ();
return (EXECUTION_FAILURE);
return (EX_USAGE);
}
any_succeeded = listing = saw_signal = 0;
@ -137,7 +139,7 @@ kill_builtin (list)
else if (ISOPTION (word, '?'))
{
builtin_usage ();
return (EXECUTION_SUCCESS);
return (EX_USAGE);
}
/* If this is a signal specification then process it. We only process
the first one seen; other arguments may signify process groups (e.g,
@ -166,7 +168,7 @@ kill_builtin (list)
if (list == 0)
{
builtin_usage ();
return (EXECUTION_FAILURE);
return (EX_USAGE);
}
while (list)

View file

@ -2,7 +2,7 @@ This file is mapfile.def, from which is created mapfile.c.
It implements the builtin "mapfile" in Bash.
Copyright (C) 2005-2006 Rocky Bernstein for Free Software Foundation, Inc.
Copyright (C) 2008-2010 Free Software Foundation, Inc.
Copyright (C) 2008-2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -125,7 +125,7 @@ run_callback (callback, curindex, curline)
#endif
snprintf (execstr, execlen, "%s %d %s", callback, curindex, qline);
free (qline);
return parse_and_execute (execstr, NULL, flags);
return evalstring (execstr, NULL, flags);
}
static void
@ -172,6 +172,8 @@ mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_n
builtin_error (_("%s: not an indexed array"), array_name);
return (EXECUTION_FAILURE);
}
else if (invisible_p (entry))
VUNSETATTR (entry, att_invisible); /* no longer invisible */
if (flags & MAPF_CLEARARRAY)
array_flush (array_cell (entry));
@ -193,7 +195,6 @@ mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_n
line_length = 0;
/* Reset the buffer for bash own stream */
interrupt_immediately++;
for (array_index = origin, line_count = 1;
zgetline (fd, &line, &line_length, unbuffered_read) != -1;
array_index++)
@ -212,6 +213,8 @@ mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_n
zsyncfd (fd);
}
/* XXX - bad things can happen if the callback modifies ENTRY, e.g.,
unsetting it or changing it to a non-indexed-array type. */
bind_array_element (entry, array_index, line, 0);
/* Have we exceeded # of lines to store? */
@ -225,7 +228,6 @@ mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_n
if (unbuffered_read == 0)
zsyncfd (fd);
interrupt_immediately--;
return EXECUTION_SUCCESS;
}

View file

@ -1,7 +1,7 @@
/* mkbuiltins.c - Create builtins.c, builtext.h, and builtdoc.c from
a single source file called builtins.def. */
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
/* Copyright (C) 1987-2011 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -85,6 +85,10 @@ int only_documentation = 0;
/* Non-zero means to not do any productions. */
int inhibit_production = 0;
/* Non-zero means to not add functions (xxx_builtin) to the members of the
produced `struct builtin []' */
int inhibit_functions = 0;
/* Non-zero means to produce separate help files for each builtin, named by
the builtin name, in `./helpfiles'. */
int separate_helpfiles = 0;
@ -198,7 +202,7 @@ void remove_trailing_whitespace ();
/* For each file mentioned on the command line, process it and
write the information to STRUCTFILE and EXTERNFILE, while
creating the production file if neccessary. */
creating the production file if necessary. */
int
main (argc, argv)
int argc;
@ -222,6 +226,8 @@ main (argc, argv)
struct_filename = argv[arg_index++];
else if (strcmp (arg, "-noproduction") == 0)
inhibit_production = 1;
else if (strcmp (arg, "-nofunctions") == 0)
inhibit_functions = 1;
else if (strcmp (arg, "-document") == 0)
documentation_file = fopen (documentation_filename, "w");
else if (strcmp (arg, "-D") == 0)
@ -322,10 +328,13 @@ main (argc, argv)
fclose (externfile);
}
#if 0
/* This is now done by a different program */
if (separate_helpfiles)
{
write_helpfiles (saved_builtins);
}
#endif
if (documentation_file)
{
@ -390,7 +399,7 @@ copy_string_array (array)
return (copy);
}
/* Add ELEMENT to ARRAY, growing the array if neccessary. */
/* Add ELEMENT to ARRAY, growing the array if necessary. */
void
array_add (element, array)
char *element;
@ -519,6 +528,7 @@ extract_info (filename, structfile, externfile)
if (nr == 0)
{
fprintf (stderr, "mkbuiltins: %s: skipping zero-length file\n", filename);
free (buffer);
return;
}
@ -537,7 +547,7 @@ extract_info (filename, structfile, externfile)
{
array_add (&buffer[i], defs->lines);
while (buffer[i] != '\n' && i < file_size)
while (i < file_size && buffer[i] != '\n')
i++;
buffer[i++] = '\0';
}
@ -1092,7 +1102,7 @@ char *structfile_header[] = {
"/* This file is manufactured by ./mkbuiltins, and should not be",
" edited by hand. See the source to mkbuiltins for details. */",
"",
"/* Copyright (C) 1987-2009 Free Software Foundation, Inc.",
"/* Copyright (C) 1987-2012 Free Software Foundation, Inc.",
"",
" This file is part of GNU Bash, the Bourne Again SHell.",
"",
@ -1138,7 +1148,7 @@ char *structfile_footer[] = {
(char *)NULL
};
/* Write out any neccessary opening information for
/* Write out any necessary opening information for
STRUCTFILE and EXTERNFILE. */
void
write_file_headers (structfile, externfile)
@ -1224,7 +1234,7 @@ write_builtins (defs, structfile, externfile)
{
fprintf (structfile, " { \"%s\", ", builtin->name);
if (builtin->function)
if (builtin->function && inhibit_functions == 0)
fprintf (structfile, "%s, ", builtin->function);
else
fprintf (structfile, "(sh_builtin_func_t *)0x0, ");
@ -1236,9 +1246,15 @@ write_builtins (defs, structfile, externfile)
(builtin->flags & BUILTIN_FLAG_POSIX_BUILTIN) ? " | POSIX_BUILTIN" : "",
document_name (builtin));
fprintf
(structfile, " N_(\"%s\"), (char *)NULL },\n",
builtin->shortdoc ? builtin->shortdoc : builtin->name);
if (inhibit_functions)
fprintf
(structfile, " N_(\"%s\"), \"%s\" },\n",
builtin->shortdoc ? builtin->shortdoc : builtin->name,
document_name (builtin));
else
fprintf
(structfile, " N_(\"%s\"), (char *)NULL },\n",
builtin->shortdoc ? builtin->shortdoc : builtin->name);
}
@ -1247,7 +1263,7 @@ write_builtins (defs, structfile, externfile)
long documentation strings. */
save_builtin (builtin);
/* Write out the matching #endif, if neccessary. */
/* Write out the matching #endif, if necessary. */
if (builtin->dependencies)
{
if (externfile)
@ -1308,6 +1324,26 @@ write_longdocs (stream, builtins)
}
}
void
write_dummy_declarations (stream, builtins)
FILE *stream;
ARRAY *builtins;
{
register int i;
BUILTIN_DESC *builtin;
for (i = 0; structfile_header[i]; i++)
fprintf (stream, "%s\n", structfile_header[i]);
for (i = 0; i < builtins->sindex; i++)
{
builtin = (BUILTIN_DESC *)builtins->array[i];
/* How to guarantee that no builtin is written more than once? */
fprintf (stream, "int %s () { return (0); }\n", builtin->function);
}
}
/* Write an #ifdef string saying what needs to be defined (or not defined)
in order to allow compilation of the code that will follow.
STREAM is the stream to write the information to,
@ -1407,7 +1443,7 @@ write_documentation (stream, documentation, indentation, flags)
base_indent = (string_array && single_longdoc_strings && filename_p == 0) ? BASE_INDENT : 0;
for (i = 0, texinfo = (flags & TEXINFO); line = documentation[i]; i++)
for (i = 0, texinfo = (flags & TEXINFO); documentation && (line = documentation[i]); i++)
{
/* Allow #ifdef's to be written out verbatim, but don't put them into
separate help files. */

View file

@ -35,14 +35,19 @@ sequences, which are converted and copied to the standard output; and
format specifications, each of which causes printing of the next successive
argument.
In addition to the standard format specifications described in printf(1)
and printf(3), printf interprets:
In addition to the standard format specifications described in printf(1),
printf interprets:
%b expand backslash escape sequences in the corresponding argument
%q quote the argument in a way that can be reused as shell input
%(fmt)T output the date-time string resulting from using FMT as a format
string for strftime(3)
The format is re-used as necessary to consume all of the arguments. If
there are fewer arguments than the format requires, extra format
specifications behave as if a zero value or null string, as appropriate,
had been supplied.
Exit Status:
Returns success unless an invalid option is given or a write or assignment
error occurs.
@ -158,7 +163,8 @@ extern int errno;
else if (vbuf) \
vbuf[0] = 0; \
terminate_immediately--; \
fflush (stdout); \
if (ferror (stdout) == 0) \
fflush (stdout); \
if (ferror (stdout)) \
{ \
sh_wrerror (); \
@ -460,7 +466,8 @@ printf_builtin (list)
timefmt[2] = '\0';
}
/* argument is seconds since the epoch with special -1 and -2 */
arg = getintmax ();
/* default argument is equivalent to -1; special case */
arg = garglist ? getintmax () : -1;
if (arg == -1)
secs = NOW; /* roughly date +%s */
else if (arg == -2)
@ -471,7 +478,12 @@ printf_builtin (list)
sv_tz ("TZ"); /* XXX -- just make sure */
#endif
tm = localtime (&secs);
n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
if (tm == 0)
{
secs = 0;
tm = localtime (&secs);
}
n = tm ? strftime (timebuf, sizeof (timebuf), timefmt, tm) : 0;
free (timefmt);
if (n == 0)
timebuf[0] = '\0';
@ -483,8 +495,11 @@ printf_builtin (list)
n = printstr (start, timebuf, strlen (timebuf), fieldwidth, precision); /* XXX - %s for now */
if (n < 0)
{
sh_wrerror ();
clearerr (stdout);
if (ferror (stdout) == 0)
{
sh_wrerror ();
clearerr (stdout);
}
PRETURN (EXECUTION_FAILURE);
}
break;
@ -524,8 +539,11 @@ printf_builtin (list)
r = printstr (start, xp, rlen, fieldwidth, precision);
if (r < 0)
{
sh_wrerror ();
clearerr (stdout);
if (ferror (stdout) == 0)
{
sh_wrerror ();
clearerr (stdout);
}
retval = EXECUTION_FAILURE;
}
free (xp);
@ -548,7 +566,7 @@ printf_builtin (list)
else if (ansic_shouldquote (p))
xp = ansic_quote (p, 0, (int *)0);
else
xp = sh_backslash_quote (p);
xp = sh_backslash_quote (p, 0, 1);
if (xp)
{
/* Use printstr to get fieldwidth and precision right. */
@ -647,8 +665,7 @@ printf_builtin (list)
if (ferror (stdout))
{
sh_wrerror ();
clearerr (stdout);
/* PRETURN will print error message. */
PRETURN (EXECUTION_FAILURE);
}
}
@ -681,12 +698,9 @@ printstr (fmt, string, len, fieldwidth, precision)
#endif
int padlen, nc, ljust, i;
int fw, pr; /* fieldwidth and precision */
intmax_t mfw, mpr;
#if 0
if (string == 0 || *string == '\0')
#else
if (string == 0 || len == 0)
#endif
return 0;
#if 0
@ -697,6 +711,8 @@ printstr (fmt, string, len, fieldwidth, precision)
ljust = fw = 0;
pr = -1;
mfw = 0;
mpr = -1;
/* skip flags */
while (strchr (SKIP1, *fmt))
@ -706,7 +722,7 @@ printstr (fmt, string, len, fieldwidth, precision)
fmt++;
}
/* get fieldwidth, if present */
/* get fieldwidth, if present. rely on caller to clamp fieldwidth at INT_MAX */
if (*fmt == '*')
{
fmt++;
@ -719,9 +735,11 @@ printstr (fmt, string, len, fieldwidth, precision)
}
else if (DIGIT (*fmt))
{
fw = *fmt++ - '0';
mfw = *fmt++ - '0';
while (DIGIT (*fmt))
fw = (fw * 10) + (*fmt++ - '0');
mfw = (mfw * 10) + (*fmt++ - '0');
/* Error if fieldwidth > INT_MAX here? */
fw = (mfw < 0 || mfw > INT_MAX) ? INT_MAX : mfw;
}
/* get precision, if present */
@ -735,9 +753,11 @@ printstr (fmt, string, len, fieldwidth, precision)
}
else if (DIGIT (*fmt))
{
pr = *fmt++ - '0';
mpr = *fmt++ - '0';
while (DIGIT (*fmt))
pr = (pr * 10) + (*fmt++ - '0');
mpr = (mpr * 10) + (*fmt++ - '0');
/* Error if precision > INT_MAX here? */
pr = (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr;
}
}
@ -745,7 +765,7 @@ printstr (fmt, string, len, fieldwidth, precision)
/* If we remove this, get rid of `s'. */
if (*fmt != 'b' && *fmt != 'q')
{
internal_error ("format parsing problem: %s", s);
internal_error (_("format parsing problem: %s"), s);
fw = pr = 0;
}
#endif
@ -861,7 +881,7 @@ tescape (estart, cp, lenp, sawc)
*cp = '\\';
return 0;
}
if (uvalue <= UCHAR_MAX)
if (uvalue <= 0x7f) /* <= 0x7f translates directly */
*cp = uvalue;
else
{
@ -1089,6 +1109,9 @@ getint ()
ret = getintmax ();
if (garglist == 0)
return ret;
if (ret > INT_MAX)
{
printf_erange (garglist->word->word);
@ -1229,12 +1252,19 @@ bind_printf_variable (name, value, flags)
char *value;
int flags;
{
SHELL_VAR *v;
#if defined (ARRAY_VARS)
if (valid_array_reference (name) == 0)
return (bind_variable (name, value, flags));
v = bind_variable (name, value, flags);
else
return (assign_array_element (name, value, flags));
v = assign_array_element (name, value, flags);
#else /* !ARRAY_VARS */
return bind_variable (name, value, flags);
v = bind_variable (name, value, flags);
#endif /* !ARRAY_VARS */
if (v && readonly_p (v) == 0 && noassign_p (v) == 0)
VUNSETATTR (v, att_invisible);
return v;
}

View file

@ -27,7 +27,7 @@ echo ""
#
# Try to avoid tempfile races. We can't really check for the file's
# existance before we run psize.aux, because `test -e' is not portable,
# existence before we run psize.aux, because `test -e' is not portable,
# `test -h' (test for symlinks) is not portable, and `test -f' only
# checks for regular files. If we used mktemp(1), we're ahead of the
# game.

View file

@ -1,7 +1,7 @@
This file is pushd.def, from which is created pushd.c. It implements the
builtins "pushd", "popd", and "dirs" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2013 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -115,7 +115,7 @@ $END
#if defined (PUSHD_AND_POPD)
#include <stdio.h>
#ifndef _MINIX
#if defined (HAVE_SYS_PARAM_H)
# include <sys/param.h>
#endif
@ -228,7 +228,7 @@ pushd_builtin (list)
{
sh_invalidnum (list->word->word);
builtin_usage ();
return (EXECUTION_FAILURE);
return (EX_USAGE);
}
if (direction == '-')
@ -245,7 +245,7 @@ pushd_builtin (list)
{
sh_invalidopt (list->word->word);
builtin_usage ();
return (EXECUTION_FAILURE);
return (EX_USAGE);
}
else
break;
@ -339,7 +339,7 @@ popd_builtin (list)
{
sh_invalidnum (list->word->word);
builtin_usage ();
return (EXECUTION_FAILURE);
return (EX_USAGE);
}
which_word = list->word->word;
}
@ -347,7 +347,13 @@ popd_builtin (list)
{
sh_invalidopt (list->word->word);
builtin_usage ();
return (EXECUTION_FAILURE);
return (EX_USAGE);
}
else if (*list->word->word)
{
builtin_error (_("%s: invalid argument"), list->word->word);
builtin_usage ();
return (EX_USAGE);
}
else
break;
@ -426,7 +432,7 @@ dirs_builtin (list)
{
sh_invalidnum (list->word->word);
builtin_usage ();
return (EXECUTION_FAILURE);
return (EX_USAGE);
}
sign = (*list->word->word == '+') ? 1 : -1;
desired_index = get_dirstack_index (i, sign, &index_flag);
@ -435,7 +441,7 @@ dirs_builtin (list)
{
sh_invalidopt (list->word->word);
builtin_usage ();
return (EXECUTION_FAILURE);
return (EX_USAGE);
}
}

View file

@ -1,7 +1,7 @@
This file is read.def, from which is created read.c.
It implements the builtin "read" in Bash.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
Copyright (C) 1987-2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -51,15 +51,17 @@ Options:
-r do not allow backslashes to escape any characters
-s do not echo input coming from a terminal
-t timeout time out and return failure if a complete line of input is
not read withint TIMEOUT seconds. The value of the TMOUT
not read within TIMEOUT seconds. The value of the TMOUT
variable is the default timeout. TIMEOUT may be a
fractional number. If TIMEOUT is 0, read returns success only
if input is available on the specified file descriptor. The
fractional number. If TIMEOUT is 0, read returns immediately,
without trying to read any data, returning success only if
input is available on the specified file descriptor. The
exit status is greater than 128 if the timeout is exceeded
-u fd read from file descriptor FD instead of the standard input
Exit Status:
The return code is zero, unless end-of-file is encountered, read times out,
The return code is zero, unless end-of-file is encountered, read times out
(in which case it's greater than 128), a variable assignment error occurs,
or an invalid file descriptor is supplied as the argument to -u.
$END
@ -101,10 +103,17 @@ $END
# include "input.h"
#endif
#include "shmbutil.h"
#if !defined(errno)
extern int errno;
#endif
extern void run_pending_traps __P((void));
extern int posixly_correct;
extern int trapped_signal_received;
struct ttsave
{
int fd;
@ -127,15 +136,26 @@ static void ttyrestore __P((struct ttsave *));
static sighandler sigalrm __P((int));
static void reset_alarm __P((void));
static procenv_t alrmbuf;
/* Try this to see what the rest of the shell can do with the information. */
procenv_t alrmbuf;
int sigalrm_seen;
static int reading;
static SigHandler *old_alrm;
static unsigned char delim;
/* In all cases, SIGALRM just sets a flag that we check periodically. This
avoids problems with the semi-tricky stuff we do with the xfree of
input_string at the top of the unwind-protect list (see below). */
/* Set a flag that CHECK_ALRM can check. This relies on zread calling
trap.c:check_signals_and_traps(), which knows about sigalrm_seen and
alrmbuf. */
static sighandler
sigalrm (s)
int s;
{
longjmp (alrmbuf, 1);
sigalrm_seen = 1;
}
static void
@ -158,7 +178,7 @@ read_builtin (list)
register char *varname;
int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
int raw, edit, nchars, silent, have_timeout, ignore_delim, fd;
int raw, edit, nchars, silent, have_timeout, ignore_delim, fd, lastsig, t_errno;
unsigned int tmsec, tmusec;
long ival, uval;
intmax_t intval;
@ -199,6 +219,9 @@ read_builtin (list)
#endif
USE_VAR(list);
USE_VAR(ps2);
USE_VAR(lastsig);
sigalrm_seen = reading = 0;
i = 0; /* Index into the string that we are reading. */
raw = edit = 0; /* Not reading raw input by default. */
@ -306,6 +329,18 @@ read_builtin (list)
return (input_avail (fd) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
#endif
/* Convenience: check early whether or not the first of possibly several
variable names is a valid identifier, and bail early if so. */
#if defined (ARRAY_VARS)
if (list && legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word) == 0)
#else
if (list && legal_identifier (list->word->word) == 0)
#endif
{
sh_invalidid (list->word->word);
return (EXECUTION_FAILURE);
}
/* If we're asked to ignore the delimiter, make sure we do. */
if (ignore_delim)
delim = -1;
@ -380,14 +415,15 @@ read_builtin (list)
if (tmsec > 0 || tmusec > 0)
{
code = setjmp (alrmbuf);
code = setjmp_nosigs (alrmbuf);
if (code)
{
sigalrm_seen = 0;
/* Tricky. The top of the unwind-protect stack is the free of
input_string. We want to run all the rest and use input_string,
so we have to save input_string temporarily, run the unwind-
protects, then restore input_string so we can use it later. */
protects, then restore input_string so we can use it later */
orig_input_string = 0;
input_string[i] = '\0'; /* make sure it's terminated */
if (i == 0)
{
@ -464,10 +500,12 @@ read_builtin (list)
/* This *must* be the top unwind-protect on the stack, so the manipulation
of the unwind-protect stack after the realloc() works right. */
add_unwind_protect (xfree, input_string);
interrupt_immediately++;
terminate_immediately++;
unbuffered_read = (nchars > 0) || (delim != '\n') || input_is_pipe;
CHECK_ALRM;
if ((nchars > 0) && (input_is_tty == 0) && ignore_delim) /* read -N */
unbuffered_read = 2;
else if ((nchars > 0) || (delim != '\n') || input_is_pipe)
unbuffered_read = 1;
if (prompt && edit == 0)
{
@ -482,6 +520,8 @@ read_builtin (list)
ps2 = 0;
for (print_ps2 = eof = retval = 0;;)
{
CHECK_ALRM;
#if defined (READLINE)
if (edit)
{
@ -492,7 +532,9 @@ read_builtin (list)
}
if (rlbuf == 0)
{
reading = 1;
rlbuf = edit_line (prompt ? prompt : "", itext);
reading = 0;
rlind = 0;
}
if (rlbuf == 0)
@ -515,26 +557,58 @@ read_builtin (list)
print_ps2 = 0;
}
if (unbuffered_read)
retval = zread (fd, &c, 1);
#if 0
if (posixly_correct == 0)
interrupt_immediately++;
#endif
reading = 1;
if (unbuffered_read == 2)
retval = posixly_correct ? zreadintr (fd, &c, 1) : zreadn (fd, &c, nchars - nr);
else if (unbuffered_read)
retval = posixly_correct ? zreadintr (fd, &c, 1) : zread (fd, &c, 1);
else
retval = zreadc (fd, &c);
retval = posixly_correct ? zreadcintr (fd, &c) : zreadc (fd, &c);
reading = 0;
#if 0
if (posixly_correct == 0)
interrupt_immediately--;
#endif
if (retval <= 0)
{
if (retval < 0 && errno == EINTR)
{
lastsig = LASTSIG();
if (lastsig == 0)
lastsig = trapped_signal_received;
run_pending_traps (); /* because interrupt_immediately is not set */
}
else
lastsig = 0;
CHECK_TERMSIG;
eof = 1;
break;
}
CHECK_ALRM;
#if defined (READLINE)
}
#endif
CHECK_ALRM;
if (i + 4 >= size) /* XXX was i + 2; use i + 4 for multibyte/read_mbchar */
{
input_string = (char *)xrealloc (input_string, size += 128);
remove_unwind_protect ();
add_unwind_protect (xfree, input_string);
char *t;
t = (char *)xrealloc (input_string, size += 128);
/* Only need to change unwind-protect if input_string changes */
if (t != input_string)
{
input_string = t;
remove_unwind_protect ();
add_unwind_protect (xfree, input_string);
}
}
/* If the next character is to be accepted verbatim, a backslash
@ -565,9 +639,12 @@ read_builtin (list)
continue;
}
if ((unsigned char)c == delim)
if (ignore_delim == 0 && (unsigned char)c == delim)
break;
if (c == '\0' && delim != '\0')
continue; /* skip NUL bytes in input */
if ((skip_ctlesc == 0 && c == CTLESC) || (skip_ctlnul == 0 && c == CTLNUL))
{
saw_escape++;
@ -576,9 +653,10 @@ read_builtin (list)
add_char:
input_string[i++] = c;
CHECK_ALRM;
#if defined (HANDLE_MULTIBYTE)
if (nchars > 0 && MB_CUR_MAX > 1)
if (nchars > 0 && MB_CUR_MAX > 1 && is_basic (c) == 0)
{
input_string[i] = '\0'; /* for simplicity and debugging */
i += read_mbchar (fd, input_string, i, c, unbuffered_read);
@ -591,15 +669,16 @@ add_char:
break;
}
input_string[i] = '\0';
CHECK_ALRM;
#if 1
if (retval < 0)
{
builtin_error (_("read error: %d: %s"), fd, strerror (errno));
t_errno = errno;
if (errno != EINTR)
builtin_error (_("read error: %d: %s"), fd, strerror (errno));
run_unwind_frame ("read_builtin");
return (EXECUTION_FAILURE);
return ((t_errno != EINTR) ? EXECUTION_FAILURE : 128+lastsig);
}
#endif
if (tmsec > 0 || tmusec > 0)
reset_alarm ();
@ -631,9 +710,6 @@ add_char:
assign_vars:
interrupt_immediately--;
terminate_immediately--;
#if defined (ARRAY_VARS)
/* If -a was given, take the string read, break it into a list of words,
an assign them to `arrayname' in turn. */
@ -658,6 +734,8 @@ assign_vars:
xfree (input_string);
return EXECUTION_FAILURE; /* existing associative array */
}
else if (invisible_p (var))
VUNSETATTR (var, att_invisible);
array_flush (array_cell (var));
alist = list_string (input_string, ifs_chars, 0);
@ -703,7 +781,7 @@ assign_vars:
var = bind_variable ("REPLY", input_string, 0);
VUNSETATTR (var, att_invisible);
free (input_string);
xfree (input_string);
return (retval);
}
@ -829,6 +907,7 @@ bind_read_variable (name, value)
char *name, *value;
{
SHELL_VAR *v;
#if defined (ARRAY_VARS)
if (valid_array_reference (name) == 0)
v = bind_variable (name, value, 0);
@ -867,6 +946,7 @@ read_mbchar (fd, string, ind, ch, unbuffered)
if (ret == (size_t)-2)
{
ps = ps_back;
/* We don't want to be interrupted during a multibyte char read */
if (unbuffered)
r = zread (fd, &c, 1);
else
@ -947,7 +1027,9 @@ edit_line (p, itext)
rl_startup_hook = set_itext;
deftext = itext;
}
ret = readline (p);
rl_attempted_completion_function = old_attempted_completion_function;
old_attempted_completion_function = (rl_completion_func_t *)NULL;

View file

@ -60,9 +60,11 @@ int
return_builtin (list)
WORD_LIST *list;
{
#if 0
if (no_options (list))
return (EX_USAGE);
list = loptend; /* skip over possible `--' */
#endif
return_catch_value = get_exitstat (list);

View file

@ -1,7 +1,7 @@
This file is set.def, from which is created set.c.
It implements the "set" and "unset" builtins in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -96,12 +96,16 @@ Options:
interactive-comments
allow comments to appear in interactive commands
keyword same as -k
#if defined (JOB_CONTROL)
monitor same as -m
#endif
noclobber same as -C
noexec same as -n
noglob same as -f
nolog currently accepted but ignored
#if defined (JOB_CONTROL)
notify same as -b
#endif
nounset same as -u
onecmd same as -t
physical same as -P
@ -135,7 +139,7 @@ Options:
-H Enable ! style history substitution. This flag is on
by default when the shell is interactive.
#endif /* BANG_HISTORY */
-P If set, do not follow symbolic links when executing commands
-P If set, do not resolve symbolic links when executing commands
such as cd which change the current directory.
-T If set, the DEBUG trap is inherited by shell functions.
-- Assign any remaining arguments to the positional parameters.
@ -205,7 +209,9 @@ const struct {
{ "ignoreeof", '\0', &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL },
{ "interactive-comments", '\0', &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "keyword", 'k', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#if defined (JOB_CONTROL)
{ "monitor", 'm', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
#endif
{ "noclobber", 'C', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "noexec", 'n', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "noglob", 'f', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
@ -718,7 +724,7 @@ set_builtin (list)
$BUILTIN unset
$FUNCTION unset_builtin
$SHORT_DOC unset [-f] [-v] [name ...]
$SHORT_DOC unset [-f] [-v] [-n] [name ...]
Unset values and attributes of shell variables and functions.
For each NAME, remove the corresponding variable or function.
@ -726,6 +732,8 @@ For each NAME, remove the corresponding variable or function.
Options:
-f treat each NAME as a shell function
-v treat each NAME as a shell variable
-n treat each NAME as a name reference and unset the variable itself
rather than the variable it references
Without options, unset first tries to unset a variable, and if that fails,
tries to unset a function.
@ -742,13 +750,13 @@ int
unset_builtin (list)
WORD_LIST *list;
{
int unset_function, unset_variable, unset_array, opt, any_failed;
int unset_function, unset_variable, unset_array, opt, nameref, any_failed;
char *name;
unset_function = unset_variable = unset_array = any_failed = 0;
unset_function = unset_variable = unset_array = nameref = any_failed = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "fv")) != -1)
while ((opt = internal_getopt (list, "fnv")) != -1)
{
switch (opt)
{
@ -758,6 +766,9 @@ unset_builtin (list)
case 'v':
unset_variable = 1;
break;
case 'n':
nameref = 1;
break;
default:
builtin_usage ();
return (EX_USAGE);
@ -771,6 +782,8 @@ unset_builtin (list)
builtin_error (_("cannot simultaneously unset a function and a variable"));
return (EXECUTION_FAILURE);
}
else if (unset_function && nameref)
nameref = 0;
while (list)
{
@ -791,6 +804,8 @@ unset_builtin (list)
unset_array++;
}
#endif
/* Get error checking out of the way first. The low-level functions
just perform the unset, relying on the caller to verify. */
/* Bash allows functions with names which are not valid identifiers
to be created when not in posix mode, so check only when in posix
@ -801,19 +816,32 @@ unset_builtin (list)
NEXT_VARIABLE ();
}
var = unset_function ? find_function (name) : find_variable (name);
/* Only search for functions here if -f supplied. */
var = unset_function ? find_function (name)
: (nameref ? find_variable_last_nameref (name) : find_variable (name));
if (var && !unset_function && non_unsettable_p (var))
/* Some variables (but not functions yet) cannot be unset, period. */
if (var && unset_function == 0 && non_unsettable_p (var))
{
builtin_error (_("%s: cannot unset"), name);
NEXT_VARIABLE ();
}
/* Posix.2 says try variables first, then functions. If we would
find a function after unsuccessfully searching for a variable,
note that we're acting on a function now as if -f were
supplied. The readonly check below takes care of it. */
if (var == 0 && unset_variable == 0 && unset_function == 0)
{
if (var = find_function (name))
unset_function = 1;
}
/* Posix.2 says that unsetting readonly variables is an error. */
if (var && readonly_p (var))
{
builtin_error (_("%s: cannot unset: readonly %s"),
name, unset_function ? "function" : "variable");
var->name, unset_function ? "function" : "variable");
NEXT_VARIABLE ();
}
@ -823,7 +851,7 @@ unset_builtin (list)
{
if (array_p (var) == 0 && assoc_p (var) == 0)
{
builtin_error (_("%s: not an array variable"), name);
builtin_error (_("%s: not an array variable"), var->name);
NEXT_VARIABLE ();
}
else
@ -835,13 +863,13 @@ unset_builtin (list)
}
else
#endif /* ARRAY_VARS */
tem = unset_function ? unbind_func (name) : unbind_variable (name);
tem = unset_function ? unbind_func (name) : (nameref ? unbind_nameref (name) : unbind_variable (name));
/* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
/* This is what Posix.2 says: ``If neither -f nor -v
is specified, the name refers to a variable; if a variable by
that name does not exist, a function by that name, if any,
shall be unset.'' */
if (tem == -1 && !unset_function && !unset_variable)
if (tem == -1 && unset_function == 0 && unset_variable == 0)
tem = unbind_func (name);
/* SUSv3, POSIX.1-2001 say: ``Unsetting a variable or function that

View file

@ -1,7 +1,7 @@
This file is setattr.def, from which is created setattr.c.
It implements the builtins "export" and "readonly", in Bash.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
Copyright (C) 1987-2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -93,7 +93,8 @@ Options:
-a refer to indexed array variables
-A refer to associative array variables
-f refer to shell functions
-p display a list of all readonly variables and functions
-p display a list of all readonly variables or functions, depending on
whether or not the -f option is given
An argument of `--' disables further option processing.
@ -368,6 +369,9 @@ show_var_attributes (var, pattr, nodefs)
if (integer_p (var))
flags[i++] = 'i';
if (nameref_p (var))
flags[i++] = 'n';
if (readonly_p (var))
flags[i++] = 'r';
@ -451,7 +455,11 @@ show_name_attributes (name, nodefs)
{
SHELL_VAR *var;
var = find_variable_internal (name, 1);
#if 0
var = find_variable_tempenv (name);
#else
var = find_variable_noref (name);
#endif
if (var && invisible_p (var) == 0)
{
@ -462,12 +470,30 @@ show_name_attributes (name, nodefs)
return (1);
}
int
show_func_attributes (name, nodefs)
char *name;
int nodefs;
{
SHELL_VAR *var;
var = find_function (name);
if (var)
{
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
return (0);
}
else
return (1);
}
void
set_var_attribute (name, attribute, undo)
char *name;
int attribute, undo;
{
SHELL_VAR *var, *tv;
SHELL_VAR *var, *tv, *v;
char *tvalue;
if (undo)
@ -484,7 +510,18 @@ set_var_attribute (name, attribute, undo)
var = bind_variable (tv->name, tvalue, 0);
var->attributes |= tv->attributes & ~att_tempvar;
VSETATTR (tv, att_propagate);
/* This avoids an error message when propagating a read-only var
later on. */
if (var->context == 0 && (attribute & att_readonly))
{
/* Don't bother to set the `propagate to the global variables
table' flag if we've just bound the variable in that table */
v = find_global_variable (tv->name);
if (v != var)
VSETATTR (tv, att_propagate);
}
else
VSETATTR (tv, att_propagate);
if (var->context != 0)
VSETATTR (var, att_propagate);
SETVARATTR (tv, attribute, undo); /* XXX */
@ -495,7 +532,7 @@ set_var_attribute (name, attribute, undo)
}
else
{
var = find_variable_internal (name, 0);
var = find_variable_notempenv (name);
if (var == 0)
{
var = bind_variable (name, (char *)NULL, 0);

View file

@ -1,7 +1,7 @@
This file is shopt.def, from which is created shopt.c.
It implements the Bash `shopt' builtin.
Copyright (C) 1994-2010 Free Software Foundation, Inc.
Copyright (C) 1994-2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -88,6 +88,7 @@ extern int gnu_error_format;
extern int check_jobs_at_exit;
extern int autocd;
extern int glob_star;
extern int glob_asciirange;
extern int lastpipe_opt;
#if defined (EXTENDED_GLOB)
@ -99,6 +100,7 @@ extern int hist_verify, history_reediting, perform_hostname_completion;
extern int no_empty_command_completion;
extern int force_fignore;
extern int dircomplete_spelling, dircomplete_expand;
extern int complete_fullquote;
extern int enable_hostname_completion __P((int));
#endif
@ -134,6 +136,7 @@ static int shopt_compat31;
static int shopt_compat32;
static int shopt_compat40;
static int shopt_compat41;
static int shopt_compat42;
typedef int shopt_set_func_t __P((char *, int));
@ -157,7 +160,9 @@ static struct {
{ "compat32", &shopt_compat32, set_compatibility_level },
{ "compat40", &shopt_compat40, set_compatibility_level },
{ "compat41", &shopt_compat41, set_compatibility_level },
{ "compat42", &shopt_compat41, set_compatibility_level },
#if defined (READLINE)
{ "complete_fullquote", &complete_fullquote, (shopt_set_func_t *)NULL},
{ "direxpand", &dircomplete_expand, shopt_set_complete_direxpand },
{ "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
#endif
@ -176,6 +181,7 @@ static struct {
{ "force_fignore", &force_fignore, (shopt_set_func_t *)NULL },
#endif
{ "globstar", &glob_star, (shopt_set_func_t *)NULL },
{ "globasciiranges", &glob_asciirange, (shopt_set_func_t *)NULL },
{ "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL },
#if defined (HISTORY)
{ "histappend", &force_append_history, (shopt_set_func_t *)NULL },
@ -298,10 +304,12 @@ reset_shopt_options ()
allow_null_glob_expansion = glob_dot_filenames = 0;
cdable_vars = mail_warning = 0;
no_exit_on_failed_exec = print_shift_error = 0;
check_hashed_filenames = cdspelling = expand_aliases = check_window_size = 0;
check_hashed_filenames = cdspelling = expand_aliases = 0;
source_uses_path = promptvars = 1;
check_window_size = CHECKWINSIZE_DEFAULT;
#if defined (EXTENDED_GLOB)
extended_glob = 0;
#endif
@ -521,16 +529,18 @@ set_compatibility_level (option_name, mode)
char *option_name;
int mode;
{
/* Need to change logic here as we add more compatibility levels */
int ind;
/* First, check option_name so we can turn off other compat options when
one is set. */
if (mode && option_name[6] == '3' && option_name[7] == '1')
shopt_compat32 = shopt_compat40 = 0;
else if (mode && option_name[6] == '3' && option_name[7] == '2')
shopt_compat31 = shopt_compat40 = 0;
else if (mode && option_name[6] == '4' && option_name[7] == '0')
shopt_compat31 = shopt_compat32 = 0;
/* If we're setting something, redo some of the work we did above in
toggle_shopt(). Unset everything and reset the appropriate option
based on OPTION_NAME. */
if (mode)
{
shopt_compat31 = shopt_compat32 = 0;
shopt_compat40 = shopt_compat41 = shopt_compat42 = 0;
ind = find_shopt (option_name);
*shopt_vars[ind].value = mode;
}
/* Then set shell_compatibility_level based on what remains */
if (shopt_compat31)
@ -539,11 +549,39 @@ set_compatibility_level (option_name, mode)
shell_compatibility_level = 32;
else if (shopt_compat40)
shell_compatibility_level = 40;
else if (shopt_compat41)
shell_compatibility_level = 41;
else if (shopt_compat42)
shell_compatibility_level = 42;
else
shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
return 0;
}
/* Set and unset the various compatibility options from the value of
shell_compatibility_level; used by sv_shcompat */
void
set_compatibility_opts ()
{
shopt_compat31 = shopt_compat32 = shopt_compat40 = shopt_compat41 = shopt_compat42 = 0;
switch (shell_compatibility_level)
{
case DEFAULT_COMPAT_LEVEL:
break;
case 42:
shopt_compat42 = 1; break;
case 41:
shopt_compat41 = 1; break;
case 40:
shopt_compat40 = 1; break;
case 32:
shopt_compat32 = 1; break;
case 31:
shopt_compat31 = 1; break;
}
}
#if defined (READLINE)
static int
shopt_set_complete_direxpand (option_name, mode)

View file

@ -84,6 +84,7 @@ Other operators:
-o OPTION True if the shell option OPTION is enabled.
-v VAR True if the shell variable VAR is set
-R VAR True if the shell variable VAR is set and is a name reference.
! EXPR True if expr is false.
EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.
EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.

View file

@ -1,7 +1,7 @@
This file is type.def, from which is created type.c.
It implements the builtin "type" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2011 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -353,7 +353,7 @@ describe_command (command, dflags)
user_command_matches (command, FS_EXEC_ONLY, found_file);
/* XXX - should that be FS_EXEC_PREFERRED? */
if (!full_path)
if (full_path == 0)
break;
/* If we found the command as itself by looking through $PATH, it
@ -375,7 +375,9 @@ describe_command (command, dflags)
else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY|CDESC_SHORTDESC))
{
f = MP_DOCWD | ((dflags & CDESC_ABSPATH) ? MP_RMDOT : 0);
full_path = sh_makepath ((char *)NULL, full_path, f);
x = sh_makepath ((char *)NULL, full_path, f);
free (full_path);
full_path = x;
}
}
/* If we require a full path and don't have one, make one */

View file

@ -23,7 +23,7 @@ $PRODUCES ulimit.c
$BUILTIN ulimit
$FUNCTION ulimit_builtin
$DEPENDS_ON !_MINIX
$SHORT_DOC ulimit [-SHacdefilmnpqrstuvx] [limit]
$SHORT_DOC ulimit [-SHabcdefilmnpqrstuvxT] [limit]
Modify shell resource limits.
Provides control over the resources available to the shell and processes
@ -50,6 +50,9 @@ Options:
-u the maximum number of user processes
-v the size of virtual memory
-x the maximum number of file locks
-T the maximum number of threads
Not all options are available on all platforms.
If LIMIT is given, it is the new value of the specified resource; the
special LIMIT values `soft', `hard', and `unlimited' stand for the
@ -70,7 +73,7 @@ $END
#include <config.h>
#include "../bashtypes.h"
#ifndef _MINIX
#if defined (HAVE_SYS_PARAM_H)
# include <sys/param.h>
#endif
@ -167,6 +170,10 @@ extern int errno;
# define RLIMIT_MAXUPROC 260
#endif
#if !defined (RLIMIT_PTHREAD) && defined (RLIMIT_NTHR)
# define RLIMIT_PTHREAD RLIMIT_NTHR
#endif
#if !defined (RLIM_INFINITY)
# define RLIM_INFINITY 0x7fffffff
#endif

View file

@ -61,10 +61,6 @@ $END
#include "common.h"
#include "bashgetopt.h"
#ifdef __LCC__
#define mode_t int
#endif
/* **************************************************************** */
/* */
/* UMASK Builtin and Helpers */

View file

@ -1,7 +1,7 @@
This file is wait.def, from which is created wait.c.
It implements the builtin "wait" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
Copyright (C) 1987-2013 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -22,33 +22,36 @@ $BUILTIN wait
$FUNCTION wait_builtin
$DEPENDS_ON JOB_CONTROL
$PRODUCES wait.c
$SHORT_DOC wait [id]
$SHORT_DOC wait [-n] [id ...]
Wait for job completion and return exit status.
Waits for the process identified by ID, which may be a process ID or a
Waits for each process identified by an ID, which may be a process ID or a
job specification, and reports its termination status. If ID is not
given, waits for all currently active child processes, and the return
status is zero. If ID is a a job specification, waits for all processes
in the job's pipeline.
in that job's pipeline.
If the -n option is supplied, waits for the next job to terminate and
returns its exit status.
Exit Status:
Returns the status of ID; fails if ID is invalid or an invalid option is
given.
Returns the status of the last ID; fails if ID is invalid or an invalid
option is given.
$END
$BUILTIN wait
$FUNCTION wait_builtin
$DEPENDS_ON !JOB_CONTROL
$SHORT_DOC wait [pid]
$SHORT_DOC wait [pid ...]
Wait for process completion and return exit status.
Waits for the specified process and reports its termination status. If
PID is not given, all currently active child processes are waited for,
and the return code is zero. PID must be a process ID.
Waits for each process specified by a PID and reports its termination status.
If PID is not given, waits for all currently active child processes,
and the return status is zero. PID must be a process ID.
Exit Status:
Returns the status of ID; fails if ID is invalid or an invalid option is
given.
Returns the status of the last PID; fails if PID is invalid or an invalid
option is given.
$END
#include <config.h>
@ -82,6 +85,7 @@ procenv_t wait_intr_buf;
do \
{ \
interrupt_immediately = old_interrupt_immediately;\
wait_signal_received = 0; \
return (s);\
} \
while (0)
@ -90,17 +94,33 @@ int
wait_builtin (list)
WORD_LIST *list;
{
int status, code;
int status, code, opt, nflag;
volatile int old_interrupt_immediately;
USE_VAR(list);
if (no_options (list))
return (EX_USAGE);
nflag = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "n")) != -1)
{
switch (opt)
{
#if defined (JOB_CONTROL)
case 'n':
nflag = 1;
break;
#endif
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
old_interrupt_immediately = interrupt_immediately;
#if 0
interrupt_immediately++;
#endif
/* POSIX.2 says: When the shell is waiting (by means of the wait utility)
for asynchronous commands to complete, the reception of a signal for
@ -120,6 +140,16 @@ wait_builtin (list)
/* We support jobs or pids.
wait <pid-or-job> [pid-or-job ...] */
#if defined (JOB_CONTROL)
if (nflag)
{
status = wait_for_any_job ();
if (status < 0)
status = 127;
WAIT_RETURN (status);
}
#endif
/* But wait without any arguments means to wait for all of the shell's
currently active background processes. */
if (list == 0)