array.c | 2 +- bashhist.c | 2 +- bashline.c | 17 +++--- braces.c | 2 +- builtins.h | 1 + builtins/bind.def | 2 +- builtins/cd.def | 4 +- builtins/declare.def | 2 +- builtins/echo.def | 2 +- builtins/enable.def | 7 ++- builtins/evalstring.c | 2 +- builtins/fc.def | 8 +-- builtins/fg_bg.def | 1 + builtins/getopt.c | 2 +- builtins/getopts.def | 1 + builtins/help.def | 2 +- builtins/history.def | 1 + builtins/mkbuiltins.c | 28 ++++++++- builtins/printf.def | 2 +- builtins/psize.sh | 24 +------- builtins/read.def | 2 +- builtins/set.def | 5 +- builtins/setattr.def | 5 +- builtins/test.def | 6 ++ builtins/type.def | 2 +- builtins/ulimit.def | 4 ++ config-top.h | 8 +-- config.h.in | 8 ++- configure.in | 7 ++- doc/Makefile.in | 10 ++-- doc/bash.1 | 36 ++++++++++- doc/bashbug.1 | 3 +- doc/bashref.texi | 17 ++++++ doc/builtins.1 | 4 +- doc/rbash.1 | 4 +- error.c | 5 +- eval.c | 5 +- execute_cmd.c | 22 +++++-- execute_cmd.h | 2 + expr.c | 7 +-- externs.h | 5 +- findcmd.c | 24 ++++++-- general.c | 2 +- hashlib.c | 2 +- jobs.c | 10 ++-- jobs.h | 4 ++ lib/glob/glob.c | 3 +- lib/glob/sm_loop.c | 12 ++-- lib/glob/smatch.c | 2 +- lib/glob/strmatch.c | 2 +- lib/malloc/stats.c | 2 +- lib/malloc/trace.c | 2 +- lib/readline/rldefs.h | 2 +- lib/sh/eaccess.c | 6 +- lib/sh/makepath.c | 2 +- lib/sh/netopen.c | 6 +- lib/sh/pathcanon.c | 2 +- lib/sh/spell.c | 2 +- lib/sh/strtrans.c | 2 +- lib/sh/tmpfile.c | 162 +++++++++----------------------------------------- lib/sh/winsize.c | 2 + lib/tilde/tilde.c | 2 +- mailcheck.c | 4 +- make_cmd.c | 85 +++++++++++++++++++++++++- parse.y | 29 +++++---- pathexp.c | 4 +- pcomplete.c | 2 + print_cmd.c | 2 +- redir.c | 10 +++- shell.c | 14 ++++- sig.c | 3 +- subst.c | 94 +++++++++++++++++++++-------- support/bashbug.sh | 45 ++++---------- support/fixlinks | 35 ++++------- support/man2html.c | 2 +- support/mkclone | 39 ++++-------- support/rlvers.sh | 24 +++----- trap.c | 11 ---- unwind_prot.c | 4 +- variables.c | 59 ++++++++++++------ y.tab.c | 2 + 81 files changed, 570 insertions(+), 430 deletions(-) diff --git a/array.c b/array.c index cee9c1f..61e4fd2 100644 --- a/array.c +++ b/array.c @@ -137,7 +137,7 @@ ARRAY_ELEMENT *s, *e; a = array_create (); a->type = array->type; - for (p = s, i = 0; p != e; p = element_forw(p), i++) { + for (p = s, i = 0, mi = 0; p != e; p = element_forw(p), i++) { n = array_create_element (element_index(p), element_value(p)); ADD_BEFORE(a->head, n); mi = element_index(n); diff --git a/bashhist.c b/bashhist.c index 3b85416..124d7dd 100644 --- a/bashhist.c +++ b/bashhist.c @@ -574,7 +574,7 @@ hc_erasedups (line) int r; using_history (); - while (temp = previous_history ()) + while ((temp = previous_history ())) { if (STREQ (temp->line, line)) { diff --git a/bashline.c b/bashline.c index fa4055e..e7de666 100644 --- a/bashline.c +++ b/bashline.c @@ -637,7 +637,7 @@ snarf_hosts_from_file (filename) if (file == 0) return; - while (temp = fgets (buffer, 255, file)) + while ((temp = fgets (buffer, 255, file))) { /* Skip to first character. */ for (i = 0; buffer[i] && cr_whitespace (buffer[i]); i++) @@ -803,7 +803,7 @@ operate_and_get_next (count, c) command being entered (if no explicit argument is given), otherwise on a command from the history file. */ -#define VI_EDIT_COMMAND "fc -e \"${VISUAL:-${EDITOR:-vi}}\"" +#define VI_EDIT_COMMAND "fc -e \"${VISUAL:-${EDITOR:-vitmp}}\"" #define EMACS_EDIT_COMMAND "fc -e \"${VISUAL:-${EDITOR:-emacs}}\"" #define POSIX_VI_EDIT_COMMAND "fc -e vi" @@ -1756,7 +1756,7 @@ bash_servicename_completion_function (text, state) setservent (0); } - while (srvent = getservent ()) + while ((srvent = getservent ())) { afound = 0; if (snamelen == 0 || (STREQN (sname, srvent->s_name, snamelen))) @@ -1812,7 +1812,7 @@ bash_groupname_completion_function (text, state) setgrent (); } - while (grent = getgrent ()) + while ((grent = getgrent ())) { if (gnamelen == 0 || (STREQN (gname, grent->gr_name, gnamelen))) break; @@ -2147,11 +2147,8 @@ _ignore_completion_names (names, name_func) ; newnames = strvec_create (nidx + 1); - if (force_fignore == 0) - { - oldnames = strvec_create (nidx - 1); - oidx = 0; - } + oldnames = (force_fignore == 0) ? strvec_create (nidx - 1) : 0; + oidx = 0; newnames[0] = names[0]; for (idx = nidx = 1; names[idx]; idx++) @@ -3087,7 +3084,7 @@ isolate_sequence (string, ind, need_dquote, startp) if (startp) *startp = delim ? ++i : i; - for (passc = 0; c = string[i]; i++) + for (passc = 0; (c = string[i]); i++) { if (passc) { diff --git a/braces.c b/braces.c index 2537397..2eac919 100644 --- a/braces.c +++ b/braces.c @@ -440,7 +440,7 @@ brace_gobbler (text, tlen, indx, satisfy) #endif i = *indx; - while (c = text[i]) + while ((c = text[i])) { if (pass_next) { diff --git a/builtins.h b/builtins.h index f75e503..3610c3e 100644 --- a/builtins.h +++ b/builtins.h @@ -40,6 +40,7 @@ #define STATIC_BUILTIN 0x4 /* This builtin is not dynamically loaded. */ #define SPECIAL_BUILTIN 0x8 /* This is a Posix `special' builtin. */ #define ASSIGNMENT_BUILTIN 0x10 /* This builtin takes assignment statements. */ +#define REQUIRES_BUILTIN 0x20 /* This builtin requires other files. */ #define BASE_INDENT 4 diff --git a/builtins/bind.def b/builtins/bind.def index 4711031..3de3726 100644 --- a/builtins/bind.def +++ b/builtins/bind.def @@ -114,7 +114,7 @@ bind_builtin (list) kmap = saved_keymap = (Keymap) NULL; flags = 0; - initfile = map_name = fun_name = unbind_name = remove_seq = (char *)NULL; + initfile = map_name = fun_name = unbind_name = remove_seq = cmd_seq = (char *)NULL; return_code = EXECUTION_SUCCESS; if (!bash_readline_initialized) diff --git a/builtins/cd.def b/builtins/cd.def index 54e328e..10d1b58 100644 --- a/builtins/cd.def +++ b/builtins/cd.def @@ -224,13 +224,13 @@ cd_builtin (list) } else if (absolute_pathname (list->word->word)) dirname = list->word->word; - else if (cdpath = get_string_value ("CDPATH")) + else if ((cdpath = get_string_value ("CDPATH"))) { dirname = list->word->word; /* Find directory in $CDPATH. */ path_index = 0; - while (path = extract_colon_unit (cdpath, &path_index)) + while ((path = extract_colon_unit (cdpath, &path_index))) { /* OPT is 1 if the path element is non-empty */ opt = path[0] != '\0'; diff --git a/builtins/declare.def b/builtins/declare.def index 4d94fac..d8dd43f 100644 --- a/builtins/declare.def +++ b/builtins/declare.def @@ -248,7 +248,7 @@ declare_internal (list, local_var) #if defined (ARRAY_VARS) compound_array_assign = simple_array_assign = 0; subscript_start = (char *)NULL; - if (t = strchr (name, '[')) /* ] */ + if ((t = strchr (name, '['))) /* ] */ { subscript_start = t; *t = '\0'; diff --git a/builtins/echo.def b/builtins/echo.def index 923c43a..0399dfc 100644 --- a/builtins/echo.def +++ b/builtins/echo.def @@ -118,7 +118,7 @@ echo_builtin (list) /* All of the options in TEMP are valid options to ECHO. Handle them. */ - while (i = *temp++) + while ((i = *temp++)) { switch (i) { diff --git a/builtins/enable.def b/builtins/enable.def index 823c38f..94f47e0 100644 --- a/builtins/enable.def +++ b/builtins/enable.def @@ -101,6 +101,9 @@ enable_builtin (list) result = EXECUTION_SUCCESS; flags = 0; +#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) + filename = NULL; +#endif reset_internal_getopt (); while ((opt = internal_getopt (list, "adnpsf:")) != -1) @@ -295,7 +298,7 @@ dyn_load_builtin (list, flags, filename) #if defined (_AIX) handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL); #else - handle = dlopen (filename, RTLD_LAZY); + handle = dlopen (filename, RTLD_NOW); #endif /* !_AIX */ if (handle == 0) @@ -336,7 +339,7 @@ dyn_load_builtin (list, flags, filename) b->flags |= SPECIAL_BUILTIN; b->handle = handle; - if (old_builtin = builtin_address_internal (name, 1)) + if ((old_builtin = builtin_address_internal (name, 1))) { replaced++; FASTCOPY ((char *)b, (char *)old_builtin, sizeof (struct builtin)); diff --git a/builtins/evalstring.c b/builtins/evalstring.c index fb03c8a..c77cbaa 100644 --- a/builtins/evalstring.c +++ b/builtins/evalstring.c @@ -231,7 +231,7 @@ parse_and_execute (string, from_file, flags) dispose_command (global_command); global_command = (COMMAND *)NULL; } - else if (command = global_command) + else if ((command = global_command)) { struct fd_bitmap *bitmap; diff --git a/builtins/fc.def b/builtins/fc.def index 101eb00..b359c72 100644 --- a/builtins/fc.def +++ b/builtins/fc.def @@ -31,7 +31,7 @@ string, which means the most recent command beginning with that string. -e ENAME selects which editor to use. Default is FCEDIT, then EDITOR, - then vi. + then vitmp. -l means list lines instead of editing. -n means no line numbers listed. @@ -107,7 +107,7 @@ extern int delete_last_history __P((void)); -e ENAME selects which editor to use. Default is FCEDIT, then EDITOR, then the editor which corresponds to the current readline editing - mode, then vi. + mode, then vitmp. -l means list lines instead of editing. -n means no line numbers listed. @@ -155,7 +155,7 @@ static void fc_addhist __P((char *)); #endif /* String to execute on a file that we want to edit. */ -#define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vi}}" +#define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vitmp}}" #if defined (STRICT_POSIX) # define POSIX_FC_EDIT_COMMAND "${FCEDIT:-ed}" #else @@ -343,7 +343,7 @@ fc_builtin (list) else { numbering = 0; - stream = sh_mktmpfp ("bash-fc", MT_USERANDOM|MT_USETMPDIR, &fn); + stream = sh_mktmpfp ("bash-fc", MT_USETMPDIR, &fn); if (stream == 0) { builtin_error (_("%s: cannot open temp file: %s"), fn ? fn : "", strerror (errno)); diff --git a/builtins/fg_bg.def b/builtins/fg_bg.def index c14381b..fe1eec0 100644 --- a/builtins/fg_bg.def +++ b/builtins/fg_bg.def @@ -150,6 +150,7 @@ fg_bg (list, foreground) goto failure; } + old_async_pid = 0; if (foreground == 0) { old_async_pid = last_asynchronous_pid; diff --git a/builtins/getopt.c b/builtins/getopt.c index b223a76..0ec120f 100644 --- a/builtins/getopt.c +++ b/builtins/getopt.c @@ -178,7 +178,7 @@ sh_getopt (argc, argv, optstring) nextchar = (char *)NULL; } - if (sh_badopt = (temp == NULL || c == ':')) + if ((sh_badopt = (temp == NULL || c == ':'))) { if (sh_opterr) BADOPT (c); diff --git a/builtins/getopts.def b/builtins/getopts.def index a9aad62..dd87dd4 100644 --- a/builtins/getopts.def +++ b/builtins/getopts.def @@ -162,6 +162,7 @@ dogetopts (argc, argv) argc -= 2; argv += 2; + old_opterr = 0; special_error = optstr[0] == ':'; if (special_error) diff --git a/builtins/help.def b/builtins/help.def index 35a6de9..44e7e5d 100644 --- a/builtins/help.def +++ b/builtins/help.def @@ -117,7 +117,7 @@ help_builtin (list) pattern = list->word->word; plen = strlen (pattern); - for (i = 0; name = shell_builtins[i].name; i++) + for (i = 0; (name = shell_builtins[i].name); i++) { QUIT; if ((strncmp (pattern, name, plen) == 0) || diff --git a/builtins/history.def b/builtins/history.def index efee005..3253710 100644 --- a/builtins/history.def +++ b/builtins/history.def @@ -105,6 +105,7 @@ history_builtin (list) intmax_t delete_offset; flags = 0; + delete_arg = NULL; reset_internal_getopt (); while ((opt = internal_getopt (list, "acd:npsrw")) != -1) { diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c index ff0bdc0..e2de810 100644 --- a/builtins/mkbuiltins.c +++ b/builtins/mkbuiltins.c @@ -69,8 +69,13 @@ extern char *strcpy (); #define whitespace(c) (((c) == ' ') || ((c) == '\t')) /* Flag values that builtins can have. */ +/* These flags are for the C code generator, + the C which is produced (./builtin.c) + includes the flags definitions found + in ../builtins.h */ #define BUILTIN_FLAG_SPECIAL 0x01 #define BUILTIN_FLAG_ASSIGNMENT 0x02 +#define BUILTIN_FLAG_REQUIRES 0x04 #define BASE_INDENT 4 @@ -154,9 +159,20 @@ char *assignment_builtins[] = (char *)NULL }; +/* The builtin commands that cause requirements on other files. */ +static char *requires_builtins[] = +{ + ".", "command", "exec", "source", +#if defined (apollo) + "inlib", +#endif + (char *)NULL +}; + /* Forward declarations. */ static int is_special_builtin (); static int is_assignment_builtin (); +static int is_requires_builtin (); #if !defined (HAVE_RENAME) static int rename (); @@ -800,6 +816,8 @@ builtin_handler (self, defs, arg) new->flags |= BUILTIN_FLAG_SPECIAL; if (is_assignment_builtin (name)) new->flags |= BUILTIN_FLAG_ASSIGNMENT; + if (is_requires_builtin (name)) + new->flags |= BUILTIN_FLAG_REQUIRES; array_add ((char *)new, defs->builtins); building_builtin = 1; @@ -1217,10 +1235,11 @@ write_builtins (defs, structfile, externfile) else fprintf (structfile, "(sh_builtin_func_t *)0x0, "); - fprintf (structfile, "%s%s%s, %s_doc,\n", + fprintf (structfile, "%s%s%s%s, %s_doc,\n", "BUILTIN_ENABLED | STATIC_BUILTIN", (builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "", (builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "", + (builtin->flags & BUILTIN_FLAG_REQUIRES) ? " | REQUIRES_BUILTIN" : "", document_name (builtin)); fprintf @@ -1561,6 +1580,13 @@ is_assignment_builtin (name) return (_find_in_table (name, assignment_builtins)); } +static int +is_requires_builtin (name) + char *name; +{ + return (_find_in_table (name, requires_builtins)); +} + #if !defined (HAVE_RENAME) static int rename (from, to) diff --git a/builtins/printf.def b/builtins/printf.def index 5a63167..c844e01 100644 --- a/builtins/printf.def +++ b/builtins/printf.def @@ -577,7 +577,7 @@ printstr (fmt, string, len, fieldwidth, precision) #else if (string == 0 || len == 0) #endif - return; + return 0; #if 0 s = fmt; diff --git a/builtins/psize.sh b/builtins/psize.sh index c4d73e1..56de799 100644 --- a/builtins/psize.sh +++ b/builtins/psize.sh @@ -3,19 +3,10 @@ # psize.sh -- determine this system's pipe size, and write a define to # pipesize.h so ulimit.c can use it. -: ${TMPDIR:=/tmp} -# try to use mktemp(1) if the system supports it -{ TMPFILE="`mktemp $TMPDIR/pipsize.XXXXXX 2>/dev/null`"; } 2>/dev/null -used_mktemp=true +TMPFILE="`mktemp -t pipsize.XXXXXXXXXX`" || exit 1 -if [ -z "$TMPFILE" ]; then - TMPNAME=pipsize.$$ - TMPFILE=$TMPDIR/$TMPNAME - used_mktemp=false -fi - -trap 'rm -f "$TMPFILE" ; exit 1' 1 2 3 6 15 -trap 'rm -f "$TMPFILE"' 0 +trap 'rm -f -- "$TMPFILE"; exit 1' HUP INT QUIT TERM +trap 'rm -f -- "$TMPFILE"' EXIT echo "/*" echo " * pipesize.h" @@ -25,15 +16,6 @@ echo " * Do not edit!" echo " */" 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, -# `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. -# -$used_mktemp || rm -f "$TMPFILE" - ./psize.aux 2>"$TMPFILE" | sleep 3 if [ -s "$TMPFILE" ]; then diff --git a/builtins/read.def b/builtins/read.def index 1c18c8d..b7a2156 100644 --- a/builtins/read.def +++ b/builtins/read.def @@ -128,7 +128,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 input_is_tty, input_is_pipe, unbuffered_read; int raw, edit, nchars, silent, have_timeout, fd; unsigned int tmout; intmax_t intval; diff --git a/builtins/set.def b/builtins/set.def index 9d86319..01c43bb 100644 --- a/builtins/set.def +++ b/builtins/set.def @@ -529,7 +529,7 @@ parse_shellopts (value) int vptr; vptr = 0; - while (vname = extract_colon_unit (value, &vptr)) + while ((vname = extract_colon_unit (value, &vptr))) { set_minus_o_option (FLAG_ON, vname); free (vname); @@ -637,7 +637,7 @@ set_builtin (list) if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+')) { - while (flag_name = *++arg) + while ((flag_name = *++arg)) { if (flag_name == '?') { @@ -761,6 +761,7 @@ unset_builtin (list) #if defined (ARRAY_VARS) unset_array = 0; + t = NULL; if (!unset_function && valid_array_reference (name)) { t = strchr (name, '['); diff --git a/builtins/setattr.def b/builtins/setattr.def index 28102bc..9189aaf 100644 --- a/builtins/setattr.def +++ b/builtins/setattr.def @@ -261,7 +261,7 @@ set_or_show_attributes (list, attribute, nodefs) if (variable_list) { - for (i = 0; var = variable_list[i]; i++) + for (i = 0; (var = variable_list[i]); i++) { #if defined (ARRAY_VARS) if (arrays_only && array_p (var) == 0) @@ -438,4 +438,7 @@ set_var_attribute (name, attribute, undo) if (var && (exported_p (var) || (attribute & att_exported))) array_needs_making++; /* XXX */ + + if (var) + stupidly_hack_special_variables (name); } diff --git a/builtins/test.def b/builtins/test.def index e51d00b..44f48a4 100644 --- a/builtins/test.def +++ b/builtins/test.def @@ -60,6 +60,9 @@ File operators: FILE1 -ef FILE2 True if file1 is a hard link to file2. +All file operators except -h and -L are acting on the target of a symbolic +link, not on the symlink itself, if FILE is a symbolic link. + String operators: -z STRING True if string is empty. @@ -89,6 +92,9 @@ Other operators: Arithmetic binary operators return true if ARG1 is equal, not-equal, less-than, less-than-or-equal, greater-than, or greater-than-or-equal than ARG2. + +See the bash manual page bash(1) for the handling of parameters (i.e. +missing parameters). $END $BUILTIN [ diff --git a/builtins/type.def b/builtins/type.def index d03ccb2..4182d37 100644 --- a/builtins/type.def +++ b/builtins/type.def @@ -331,7 +331,7 @@ describe_command (command, dflags) whether the file is present in our hash table. */ if (all == 0 || (dflags & CDESC_FORCE_PATH)) { - if (full_path = phash_search (command)) + if ((full_path = phash_search (command))) { if (dflags & CDESC_TYPE) puts ("file"); diff --git a/builtins/ulimit.def b/builtins/ulimit.def index 2d2e7b2..c1d1863 100644 --- a/builtins/ulimit.def +++ b/builtins/ulimit.def @@ -182,7 +182,9 @@ static int set_limit __P((int, RLIMTYPE, int)); static void printone __P((int, RLIMTYPE, int)); static void print_all_limits __P((int)); +#ifdef NOTYET static int set_all_limits __P((int, RLIMTYPE)); +#endif static int filesize __P((RLIMTYPE *)); static int pipesize __P((RLIMTYPE *)); @@ -707,6 +709,7 @@ printone (limind, curlim, pdesc) print_rlimtype ((curlim / limits[limind].block_factor), 1); } +#ifdef NOTYET /* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which causes all limits to be set as high as possible depending on mode (like csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits @@ -746,5 +749,6 @@ set_all_limits (mode, newlim) } return retval; } +#endif #endif /* !_MINIX */ diff --git a/config-top.h b/config-top.h index 7a90b16..e3fbec3 100644 --- a/config-top.h +++ b/config-top.h @@ -52,14 +52,14 @@ /* The default value of the PATH variable. */ #ifndef DEFAULT_PATH_VALUE #define DEFAULT_PATH_VALUE \ - "/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:." + "/bin:/usr/bin:/usr/local/bin" #endif /* The value for PATH when invoking `command -p'. This is only used when the Posix.2 confstr () function, or CS_PATH define are not present. */ #ifndef STANDARD_UTILS_PATH #define STANDARD_UTILS_PATH \ - "/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc" + "/bin:/usr/bin:/sbin:/usr/sbin" #endif /* Default primary and secondary prompt strings. */ @@ -80,8 +80,8 @@ /* Define this to make non-interactive shells begun with argv[0][0] == '-' run the startup files when not in posix mode. */ -/* #define NON_INTERACTIVE_LOGIN_SHELLS */ +#define NON_INTERACTIVE_LOGIN_SHELLS /* Define this if you want bash to try to check whether it's being run by sshd and source the .bashrc if so (like the rshd behavior). */ -/* #define SSH_SOURCE_BASHRC */ +#define SSH_SOURCE_BASHRC diff --git a/config.h.in b/config.h.in index 3699374..d76e59b 100644 --- a/config.h.in +++ b/config.h.in @@ -201,7 +201,7 @@ /* System paths */ -#define DEFAULT_MAIL_DIRECTORY "/usr/spool/mail" +#define DEFAULT_MAIL_DIRECTORY "/var/mail" /* Characteristics of the system's header files and libraries that affect the compilation environment. */ @@ -654,6 +654,9 @@ /* Define if you have the raise function. */ #undef HAVE_RAISE +/* Define if you have the random function. */ +#undef HAVE_RANDOM + /* Define if you have the readlink function. */ #undef HAVE_READLINK @@ -703,6 +706,9 @@ /* Define if you have the snprintf function. */ #undef HAVE_SNPRINTF +/* Define if you have the srandom function. */ +#undef HAVE_SRANDOM + /* Define if you have the strcasecmp function. */ #undef HAVE_STRCASECMP diff --git a/configure.in b/configure.in index a688b2d..ca88819 100644 --- a/configure.in +++ b/configure.in @@ -27,7 +27,7 @@ AC_REVISION([for Bash 3.2, version 3.190])dnl define(bashvers, 3.2) define(relstatus, release) -AC_INIT([bash], bashvers-relstatus, [bug-bash@gnu.org]) +AC_INIT([bash3], bashvers-relstatus, [bug-bash@gnu.org]) dnl make sure we are using a recent autoconf version AC_PREREQ(2.50) @@ -325,7 +325,7 @@ fi HELPDIR= HELPDIRDEFINE= HELPINSTALL= if test "$opt_separate_help" != no; then if test "$opt_separate_help" = "yes" ; then - HELPDIR='${datadir}/bash' + HELPDIR='${datadir}/AC_PACKAGE_NAME' else HELPDIR=$opt_separate_help fi @@ -748,6 +748,9 @@ BASH_CHECK_DECL(strtoumax) AC_FUNC_MKTIME +dnl checks for random functions +AC_CHECK_FUNCS(random srandom) + dnl dnl Checks for lib/intl and related code (uses some of the output from dnl AM_GNU_GETTEXT) diff --git a/doc/Makefile.in b/doc/Makefile.in index 270ddfd..2c9c60c 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -69,7 +69,6 @@ TEXI2DVI = ${SUPPORT_SRCDIR}/texi2dvi TEXI2HTML = ${SUPPORT_SRCDIR}/texi2html MAN2HTML = ${BUILD_DIR}/support/man2html HTMLPOST = ${srcdir}/htmlpost.sh -INFOPOST = ${srcdir}/infopost.sh QUIETPS = #set this to -q to shut up dvips PAPERSIZE = letter # change to a4 for A4-size paper PSDPI = 600 # could be 300 if you like @@ -146,7 +145,7 @@ nodvi: ps info text html PSFILES = bash.ps bashbug.ps article.ps builtins.ps rbash.ps DVIFILES = bashref.dvi bashref.ps -INFOFILES = bashref.info +INFOFILES = bashref.info bash.info MAN0FILES = bash.0 bashbug.0 builtins.0 rbash.0 HTMLFILES = bashref.html bash.html PDFFILES = bash.pdf bashref.pdf article.pdf rose94.pdf @@ -167,8 +166,8 @@ bashref.info: $(BASHREF_FILES) $(HSUSER) $(RLUSER) bashref.html: $(BASHREF_FILES) $(HSUSER) $(RLUSER) $(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/bashref.texi -bash.info: bashref.info - ${SHELL} ${INFOPOST} < $(srcdir)/bashref.info > $@ ; \ +bash.info: $(BASHREF_FILES) $(HSUSER) $(RLUSER) + $(MAKEINFO) --no-split -I$(TEXINPUTDIR) $(srcdir)/bashref.texi -o $@ bash.txt: bash.1 bash.ps: bash.1 @@ -222,9 +221,10 @@ installdirs: install: info installdirs bash.info -$(INSTALL_DATA) $(srcdir)/bash.1 $(DESTDIR)$(man1dir)/bash${man1ext} + -$(INSTALL_DATA) $(srcdir)/rbash.1 $(DESTDIR)$(man1dir)/rbash${man1ext} -$(INSTALL_DATA) $(srcdir)/bashbug.1 $(DESTDIR)$(man1dir)/bashbug${man1ext} # uncomment the next line to install the builtins man page -# -$(INSTALL_DATA) $(srcdir)/builtins.1 $(DESTDIR)$(man1dir)/bash_builtins${man1ext} + -$(INSTALL_DATA) $(srcdir)/builtins.1 $(DESTDIR)$(man1dir)/builtins${man1ext} -$(INSTALL_DATA) $(srcdir)/bash.info $(DESTDIR)$(infodir)/bash.info # run install-info if it is present to update the info directory if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \ diff --git a/doc/bash.1 b/doc/bash.1 index 4d977f9..8c336c1 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -116,6 +116,12 @@ processing, then commands are read from the standard input. This option allows the positional parameters to be set when invoking an interactive shell. .TP +.B \-v +Print shell input lines as they are read. +.TP +.B \-x +Print commands and their arguments as they are executed. +.TP .B \-D A list of all double-quoted strings preceded by \fB$\fP is printed on the standard output. @@ -232,6 +238,13 @@ The shell becomes restricted (see .B "RESTRICTED SHELL" below). .TP +.B \-\-rpm-requires +Produce the list of files that are required for the +shell script to run. This implies '-n' and is subject +to the same limitations as compile time error checking checking; +Backticks, [] tests, and evals are not parsed so some +dependencies may be missed. +.TP .B \-\-verbose Equivalent to \fB\-v\fP. .TP @@ -1647,7 +1660,9 @@ A filename whose suffix matches one of the entries in is excluded from the list of matched filenames. A sample value is .if t \f(CW".o:~"\fP. -.if n ".o:~". +.if n ".o:~" +(Quoting is needed when assigning a value to this variable, +which contains tildes). .TP .B GLOBIGNORE A colon-separated list of patterns defining the set of filenames to @@ -2420,6 +2435,9 @@ below). \fIlength\fP must evaluate to a number greater than or equal to zero. If \fIoffset\fP evaluates to a number less than zero, the value is used as an offset from the end of the value of \fIparameter\fP. +Arithmetic expressions starting with a - must be separated by whitespace +from the preceding : to be +distinguished from the \fBUse Default Values\fP expansion. If \fIparameter\fP is \fB@\fP, the result is \fIlength\fP positional parameters beginning at \fIoffset\fP. If \fIparameter\fP is an array name indexed by @ or *, @@ -2611,6 +2629,9 @@ and the substitution of the result. The format for arithmetic expansion is: \fB$((\fP\fIexpression\fP\fB))\fP .RE .PP +The old format \fB$[\fP\fIexpression\fP\fB]\fP is deprecated and will +be removed in upcoming versions of bash. +.PP The .I expression is treated as if it were within double quotes, but a double quote @@ -2748,6 +2769,10 @@ If the shell option .B nocaseglob is enabled, the match is performed without regard to the case of alphabetic characters. +Note that when using range expressions like +[a-z] (see below), letters of the other case may be included, +depending on the setting of +.B LC_COLLATE. When a pattern is used for pathname expansion, the character .B ``.'' @@ -3014,6 +3039,9 @@ a UDP connection to the corresponding socket. .PD .RE .PP +\fBNOTE:\fP This Bash build does \fBnot\fP support using +the \fB/dev/tcp\fP and \fB/dev/udp\fP files. +.PP A failure to open or create a file causes the redirection to fail. .PP Redirections using file descriptors greater than 9 should be used with @@ -3543,6 +3571,10 @@ descriptor 0, 1, or 2, respectively, is checked. .PP Unless otherwise specified, primaries that operate on files follow symbolic links and operate on the target of the link, rather than the link itself. +.PP +See the description of the \fItest\fP builtin command (section SHELL +BUILTIN COMMANDS below) for the handling of parameters (i.e. +missing parameters). .sp 1 .PD 0 .TP @@ -6839,7 +6871,7 @@ if .SM .B FCEDIT is not set. If neither variable is set, -.FN vi +.FN vitmp is used. When editing is complete, the edited commands are echoed and executed. .sp 1 diff --git a/doc/bashbug.1 b/doc/bashbug.1 index 971e4c4..fefe156 100644 --- a/doc/bashbug.1 +++ b/doc/bashbug.1 @@ -35,7 +35,8 @@ Specifies the preferred editor. If is not set, .B bashbug defaults to -.BR emacs . +an instance of +.BR vi . .TP .B HOME Directory in which the failed bug report is saved if the mail fails. diff --git a/doc/bashref.texi b/doc/bashref.texi index c2892d6..4f618b4 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -1589,6 +1589,9 @@ This is referred to as Substring Expansion. @var{length} must evaluate to a number greater than or equal to zero. If @var{offset} evaluates to a number less than zero, the value is used as an offset from the end of the value of @var{parameter}. +Arithmetic expressions starting with a - must be separated by whitespace +from the preceding : to be +distinguished from the $@{@var{parameter}:@minus{}@var{word}@} expansion. If @var{parameter} is @samp{@@}, the result is @var{length} positional parameters beginning at @var{offset}. If @var{parameter} is an array name indexed by @samp{@@} or @samp{*}, @@ -2025,6 +2028,9 @@ If @var{host} is a valid hostname or Internet address, and @var{port} is an integer port number or service name, Bash attempts to open a UDP connection to the corresponding socket. +NOTE: This @code{Bash} build does not support using the +@file{/dev/tcp} and @file{/dev/udp} files. + @end table A failure to open or create a file causes the redirection to fail. @@ -4906,6 +4912,13 @@ standard. @xref{Bash POSIX Mode}, for a description of the Bash @item --restricted Make the shell a restricted shell (@pxref{The Restricted Shell}). +@item --rpm-requires +Produce the list of files that are required for the +shell script to run. This implies '-n' and is subject +to the same limitations as compile time error checking checking; +Backticks, [] tests, and evals are not parsed so some +dependencies may be missed. + @item --verbose Equivalent to @option{-v}. Print shell input lines as they're read. @@ -5285,6 +5298,10 @@ descriptor 0, 1, or 2, respectively, is checked. Unless otherwise specified, primaries that operate on files follow symbolic links and operate on the target of the link, rather than the link itself. +See the description of the @code{test} builtin command (section +@pxref{Bash Builtins} below) for the handling of parameters +(i.e. missing parameters). + @table @code @item -a @var{file} True if @var{file} exists. diff --git a/doc/builtins.1 b/doc/builtins.1 index 6a0b248..0e25b2d 100644 --- a/doc/builtins.1 +++ b/doc/builtins.1 @@ -7,8 +7,8 @@ continue, declare, dirs, disown, echo, enable, eval, exec, exit, export, fc, fg, getopts, hash, help, history, jobs, kill, let, local, logout, popd, printf, pushd, pwd, read, readonly, return, set, shift, shopt, source, suspend, test, times, trap, type, typeset, -ulimit, umask, unalias, unset, wait \- bash built-in commands, see \fBbash\fR(1) -.SH BASH BUILTIN COMMANDS +ulimit, umask, unalias, unset, wait \- bash built-in commands +.SH "BASH BUILTIN COMMANDS" .nr zZ 1 .so bash.1 .SH SEE ALSO diff --git a/doc/rbash.1 b/doc/rbash.1 index c148abf..e4bb507 100644 --- a/doc/rbash.1 +++ b/doc/rbash.1 @@ -1,7 +1,7 @@ .TH RBASH 1 "2004 Apr 20" "GNU Bash-3.0" .SH NAME -rbash \- restricted bash, see \fBbash\fR(1) -.SH RESTRICTED SHELL +rbash \- restricted bash +.SH "RESTRICTED SHELL" .nr zY 1 .so bash.1 .SH SEE ALSO diff --git a/error.c b/error.c index 83f6a7a..0cf1176 100644 --- a/error.c +++ b/error.c @@ -144,7 +144,9 @@ programming_error (format, va_alist) #endif { va_list args; +#if defined (HISTORY) char *h; +#endif #if defined (JOB_CONTROL) give_terminal_to (shell_pgrp, 0); @@ -358,6 +360,7 @@ itrace (format, va_alist) /* A trace function for silent debugging -- doesn't require a control terminal. */ +/* Unused. */ void #if defined (PREFER_STDARG) trace (const char *format, ...) @@ -371,7 +374,7 @@ trace (format, va_alist) static FILE *tracefp = (FILE *)NULL; if (tracefp == NULL) - tracefp = fopen("/tmp/bash-trace.log", "a+"); + tracefp = fopen("/var/run/bash-trace.log", "a+"); if (tracefp == NULL) tracefp = stderr; diff --git a/eval.c b/eval.c index bae6c5b..c7271ad 100644 --- a/eval.c +++ b/eval.c @@ -53,6 +53,7 @@ extern int last_command_exit_value, stdin_redir; extern int need_here_doc; extern int current_command_number, current_command_line_count, line_number; extern int expand_aliases; +extern int rpm_requires; static void send_pwd_to_eterm __P((void)); static sighandler alrm_catcher __P((int)); @@ -131,13 +132,13 @@ reader_loop () if (read_command () == 0) { - if (interactive_shell == 0 && read_but_dont_execute) + if (interactive_shell == 0 && (read_but_dont_execute && !rpm_requires)) { last_command_exit_value = EXECUTION_SUCCESS; dispose_command (global_command); global_command = (COMMAND *)NULL; } - else if (current_command = global_command) + else if ((current_command = global_command)) { global_command = (COMMAND *)NULL; current_command_number++; diff --git a/execute_cmd.c b/execute_cmd.c index 81de1dc..943cafc 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -476,6 +476,8 @@ async_redirect_stdin () #define DESCRIBE_PID(pid) do { if (interactive) describe_pid (pid); } while (0) +extern int rpm_requires; + /* Execute the command passed in COMMAND, perhaps doing it asynchrounously. COMMAND is exactly what read_command () places into GLOBAL_COMMAND. ASYNCHROUNOUS, if non-zero, says to do this command in the background. @@ -507,7 +509,15 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out, #else if (breaking || continuing) return (last_command_exit_value); - if (command == 0 || read_but_dont_execute) + if (command == 0 || (read_but_dont_execute && !rpm_requires)) + return (EXECUTION_SUCCESS); + + if (rpm_requires && command->type == cm_function_def) + return last_command_exit_value = + execute_intern_function (command->value.Function_def->name, + command->value.Function_def->command); + + if (read_but_dont_execute) return (EXECUTION_SUCCESS); #endif @@ -891,6 +901,8 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out, # endif set_pipestatus_from_exit (exec_result); break; + default: + break; } #endif @@ -2542,8 +2554,8 @@ execute_cond_node (cond) else if (cond->type == COND_BINARY) { rmatch = 0; - patmatch = ((cond->op->word[1] == '=') && (cond->op->word[2] == '\0') && - (cond->op->word[0] == '!' || cond->op->word[0] == '=') || + patmatch = (((cond->op->word[1] == '=') && (cond->op->word[2] == '\0') && + (cond->op->word[0] == '!' || cond->op->word[0] == '=')) || (cond->op->word[0] == '=' && cond->op->word[1] == '\0')); #if defined (COND_REGEXP) rmatch = (cond->op->word[0] == '=' && cond->op->word[1] == '~' && @@ -3739,7 +3751,9 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out, } else { +#if defined (RESTRICTED_SHELL) parent_return: +#endif /* RESTRICTED_SHELL */ /* Make sure that the pipes are closed in the parent. */ close_pipes (pipe_in, pipe_out); #if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD) @@ -4073,7 +4087,7 @@ execute_intern_function (name, function) if (check_identifier (name, posixly_correct) == 0) { - if (posixly_correct && interactive_shell == 0) + if (posixly_correct && interactive_shell == 0 && rpm_requires == 0) { last_command_exit_value = EX_USAGE; jump_to_top_level (ERREXIT); diff --git a/execute_cmd.h b/execute_cmd.h index 6de86be..2b34715 100644 --- a/execute_cmd.h +++ b/execute_cmd.h @@ -22,6 +22,8 @@ #define _EXECUTE_CMD_H_ #include "stdc.h" +#include "variables.h" +#include "command.h" extern struct fd_bitmap *new_fd_bitmap __P((int)); extern void dispose_fd_bitmap __P((struct fd_bitmap *)); diff --git a/expr.c b/expr.c index a5cb038..2c04138 100644 --- a/expr.c +++ b/expr.c @@ -418,11 +418,8 @@ expassign () if (lasttok != STR) evalerror (_("attempted assignment to non-variable")); - if (special) - { - op = assigntok; /* a OP= b */ - lvalue = value; - } + op = assigntok; /* a OP= b */ + lvalue = value; lhs = savestring (tokstr); readtok (); diff --git a/externs.h b/externs.h index bc28eda..a5f8d66 100644 --- a/externs.h +++ b/externs.h @@ -367,9 +367,10 @@ extern void print_timeval (); /* declarations for functions defined in lib/sh/tmpfile.c */ #define MT_USETMPDIR 0x0001 #define MT_READWRITE 0x0002 -#define MT_USERANDOM 0x0004 -extern char *sh_mktmpname __P((char *, int)); +#if !defined(HAVE_DEV_FD) +extern char *sh_mktmpname_unsafe __P((char *, int)); +#endif extern int sh_mktmpfd __P((char *, int, char **)); /* extern FILE *sh_mktmpfp __P((char *, int, char **)); */ diff --git a/findcmd.c b/findcmd.c index 27720f8..0cb070f 100644 --- a/findcmd.c +++ b/findcmd.c @@ -94,7 +94,22 @@ file_status (name) r = FS_EXISTS; -#if defined (AFS) +#if defined (HAVE_EACCESS) /* FreeBSD, GLIBC_2.4+ */ + + /* For support of ACL's use eaccess(3) if found e.g. glibc 2.4 and up: + * Like access(2), euidaccess(3) checks permissions and existence of the + * file identified by its argument pathname. However, whereas access(2), + * performs checks using the real user and group identifiers of the pro- + * cess, euidaccess(3) uses the effective identifiers. + * eaccess(3) is a synonym for euidaccess(3), provided for compatibility + * with some other systems. */ + if (eaccess (name, X_OK) == 0) + r |= FS_EXECABLE; + if (eaccess (name, R_OK) == 0) + r |= FS_READABLE; + +#elif defined (AFS) + /* We have to use access(2) to determine access because AFS does not support Unix file system semantics. This may produce wrong answers for non-AFS files when ruid != euid. I hate AFS. */ @@ -103,8 +118,7 @@ file_status (name) if (access (name, R_OK) == 0) r |= FS_READABLE; - return r; -#else /* !AFS */ +#else /* !AFS && !HAVE_EACCESS */ /* Find out if the file is actually executable. By definition, the only other criteria is that the file has an execute bit set that @@ -147,8 +161,8 @@ file_status (name) r |= FS_READABLE; } +#endif /* !AFS && !HAVE_EACCESS */ return r; -#endif /* !AFS */ } /* Return non-zero if FILE exists and is executable. @@ -216,7 +230,7 @@ _find_user_command_internal (name, flags) /* Search for the value of PATH in both the temporary environments and in the regular list of variables. */ - if (var = find_variable_internal ("PATH", 1)) /* XXX could be array? */ + if ((var = find_variable_internal ("PATH", 1))) /* XXX could be array? */ path_list = value_cell (var); else path_list = (char *)NULL; diff --git a/general.c b/general.c index 4ac4de0..a3538ff 100644 --- a/general.c +++ b/general.c @@ -274,7 +274,7 @@ assignment (string, flags) #endif return (0); - while (c = string[indx]) + while ((c = string[indx])) { /* The following is safe. Note that '=' at the start of a word is not an assignment statement. */ diff --git a/hashlib.c b/hashlib.c index 456272a..5e97c64 100644 --- a/hashlib.c +++ b/hashlib.c @@ -81,7 +81,7 @@ copy_bucket_array (ba, cpdata) if (ba == 0) return ((BUCKET_CONTENTS *)0); - for (n = (BUCKET_CONTENTS *)0, e = ba; e; e = e->next) + for (new_bucket = n = (BUCKET_CONTENTS *)0, e = ba; e; e = e->next) { if (n == 0) { diff --git a/jobs.c b/jobs.c index d183394..6f34338 100644 --- a/jobs.c +++ b/jobs.c @@ -213,7 +213,7 @@ int already_making_children = 0; /* If this is non-zero, $LINES and $COLUMNS are reset after every process exits from get_tty_state(). */ -int check_window_size; +int check_window_size = 1; /* Functions local to this file. */ @@ -1050,7 +1050,7 @@ nohup_job (job_index) if (js.j_jobslots == 0) return; - if (temp = jobs[job_index]) + if ((temp = jobs[job_index])) temp->flags |= J_NOHUP; } @@ -2311,7 +2311,6 @@ wait_for (pid) WAIT s; register PROCESS *child; sigset_t set, oset; - register PROCESS *p; /* In the case that this code is interrupted, and we longjmp () out of it, we are relying on the code in throw_to_top_level () to restore the @@ -3596,8 +3595,7 @@ initialize_job_control (force) change_flag ('m', job_control ? '-' : '+'); - if (interactive) - get_tty_state (); + get_tty_state (); if (js.c_childmax < 0) js.c_childmax = getmaxchild (); @@ -4100,11 +4098,13 @@ pipe_close (pp) pp[0] = pp[1] = -1; } +#if defined (JOB_CONTROL) /* Functional interface closes our local-to-job-control pipes. */ void close_pgrp_pipe () { pipe_close (pgrp_pipe); } +#endif /* JOB_CONTROL */ #endif /* PGRP_PIPE */ diff --git a/jobs.h b/jobs.h index 93a42fb..c56f655 100644 --- a/jobs.h +++ b/jobs.h @@ -229,6 +229,10 @@ extern void default_tty_job_signals __P((void)); extern void init_job_stats __P((void)); +#if defined (JOB_CONTROL) && defined (PGRP_PIPE) +extern void close_pgrp_pipe __P((void)); +#endif + #if defined (JOB_CONTROL) extern int job_control; #endif diff --git a/lib/glob/glob.c b/lib/glob/glob.c index 08a7da8..3a4eec4 100644 --- a/lib/glob/glob.c +++ b/lib/glob/glob.c @@ -46,6 +46,7 @@ #include "stdc.h" #include "memalloc.h" #include "quit.h" +#include "sig.h" #include "glob.h" #include "strmatch.h" @@ -357,7 +358,7 @@ glob_vector (pat, dir, flags) struct globval *firstmalloc, *tmplink; lastlink = 0; - count = lose = skip = 0; + count = lose = skip = nalloca = 0; firstmalloc = 0; nalloca = 0; diff --git a/lib/glob/sm_loop.c b/lib/glob/sm_loop.c index 41b0759..cb2982f 100644 --- a/lib/glob/sm_loop.c +++ b/lib/glob/sm_loop.c @@ -301,7 +301,7 @@ BRACKMATCH (p, test, flags) circumflex (`^') in its role in a `nonmatching list'. A bracket expression starting with an unquoted circumflex character produces unspecified results. This implementation treats the two identically. */ - if (not = (*p == L('!') || *p == L('^'))) + if ((not = (*p == L('!') || *p == L('^')))) ++p; c = *p++; @@ -529,7 +529,7 @@ PATSCAN (string, end, delim) cchar = 0; bfirst = NULL; - for (s = string; c = *s; s++) + for (s = string; (c = *s); s++) { if (s >= end) return (s); @@ -610,7 +610,7 @@ STRCOMPARE (p, pe, s, se) c2 = *se; *pe = *se = '\0'; -#if HAVE_MULTIBYTE || defined (HAVE_STRCOLL) +#if HANDLE_MULTIBYTE || defined (HAVE_STRCOLL) ret = STRCOLL ((XCHAR *)p, (XCHAR *)s); #else ret = STRCMP ((XCHAR *)p, (XCHAR *)s); @@ -682,9 +682,9 @@ fprintf(stderr, "extmatch: flags = %d\n", flags); xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags; m2 = (GMATCH (srest, se, prest, pe, xflags) == 0) || (s != srest && GMATCH (srest, se, p - 1, pe, xflags) == 0); + if (m2) + return (0); } - if (m1 && m2) - return (0); } if (pnext == prest) break; @@ -727,7 +727,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags); { pnext = PATSCAN (psub, pe, L('|')); /* If one of the patterns matches, just bail immediately. */ - if (m1 = (GMATCH (s, srest, psub, pnext - 1, flags) == 0)) + if ((m1 = (GMATCH (s, srest, psub, pnext - 1, flags) == 0))) break; if (pnext == prest) break; diff --git a/lib/glob/smatch.c b/lib/glob/smatch.c index be4f927..0b08e99 100644 --- a/lib/glob/smatch.c +++ b/lib/glob/smatch.c @@ -353,7 +353,7 @@ is_wcclass (wc, name) #define IS_CCLASS(C, S) is_wcclass((C), (S)) #include "sm_loop.c" -#endif /* HAVE_MULTIBYTE */ +#endif /* HANDLE_MULTIBYTE */ int xstrmatch (pattern, string, flags) diff --git a/lib/glob/strmatch.c b/lib/glob/strmatch.c index 4d9c68d..ff3b5a1 100644 --- a/lib/glob/strmatch.c +++ b/lib/glob/strmatch.c @@ -25,7 +25,7 @@ #include "strmatch.h" extern int xstrmatch __P((char *, char *, int)); -#if defined (HAVE_MULTIBYTE) +#if defined (HANDLE_MULTIBYTE) extern int internal_wstrmatch __P((wchar_t *, wchar_t *, int)); #endif diff --git a/lib/malloc/stats.c b/lib/malloc/stats.c index 0d119fa..593260e 100644 --- a/lib/malloc/stats.c +++ b/lib/malloc/stats.c @@ -132,7 +132,7 @@ fprint_malloc_stats (s, fp) _print_malloc_stats (s, fp); } -#define TRACEROOT "/var/tmp/maltrace/stats." +#define TRACEROOT "/var/run/maltrace/stats." void trace_malloc_stats (s, fn) diff --git a/lib/malloc/trace.c b/lib/malloc/trace.c index 79f4668..37e0e11 100644 --- a/lib/malloc/trace.c +++ b/lib/malloc/trace.c @@ -107,7 +107,7 @@ malloc_trace_bin (n) #endif } -#define TRACEROOT "/var/tmp/maltrace/trace." +#define TRACEROOT "/var/run/maltrace/trace." void malloc_set_tracefn (s, fn) diff --git a/lib/readline/rldefs.h b/lib/readline/rldefs.h index 0f6c874..609c4a6 100644 --- a/lib/readline/rldefs.h +++ b/lib/readline/rldefs.h @@ -81,7 +81,7 @@ extern int _rl_stricmp PARAMS((char *, char *)); extern int _rl_strnicmp PARAMS((char *, char *, int)); #endif -#if defined (HAVE_STRPBRK) && !defined (HAVE_MULTIBYTE) +#if defined (HAVE_STRPBRK) && !defined (HANDLE_MULTIBYTE) # define _rl_strpbrk(a,b) strpbrk((a),(b)) #else extern char *_rl_strpbrk PARAMS((const char *, const char *)); diff --git a/lib/sh/eaccess.c b/lib/sh/eaccess.c index 1cff692..0c6e2bf 100644 --- a/lib/sh/eaccess.c +++ b/lib/sh/eaccess.c @@ -54,7 +54,7 @@ extern int errno; static int path_is_devfd __P((const char *)); static int sh_stataccess __P((char *, int)); -#if HAVE_DECL_SETREGID +#if HAVE_DECL_SETREGID && !defined (HAVE_EACCESS) && !defined (EFF_ONLY_OK) static int sh_euidaccess __P((char *, int)); #endif @@ -165,7 +165,7 @@ sh_stataccess (path, mode) return (-1); } -#if HAVE_DECL_SETREGID +#if HAVE_DECL_SETREGID && !defined (HAVE_EACCESS) && !defined (EFF_ONLY_OK) /* Version to call when uid != euid or gid != egid. We temporarily swap the effective and real uid and gid as appropriate. */ static int @@ -201,7 +201,7 @@ sh_eaccess (path, mode) if (path_is_devfd (path)) return (sh_stataccess (path, mode)); -#if defined (HAVE_EACCESS) /* FreeBSD */ +#if defined (HAVE_EACCESS) /* FreeBSD, GLIBC_2.4+ */ return (eaccess (path, mode)); #elif defined (EFF_ONLY_OK) /* SVR4(?), SVR4.2 */ return access (path, mode|EFF_ONLY_OK); diff --git a/lib/sh/makepath.c b/lib/sh/makepath.c index c496154..3628822 100644 --- a/lib/sh/makepath.c +++ b/lib/sh/makepath.c @@ -110,7 +110,7 @@ sh_makepath (path, dir, flags) if (s[-1] != '/') *r++ = '/'; s = xdir; - while (*r++ = *s++) + while ((*r++ = *s++)) ; if (xpath != path) free (xpath); diff --git a/lib/sh/netopen.c b/lib/sh/netopen.c index d8eec75..71d699c 100644 --- a/lib/sh/netopen.c +++ b/lib/sh/netopen.c @@ -25,6 +25,8 @@ #include +#if defined (NETWORK_REDIRECTIONS) + #if defined (HAVE_NETWORK) #if defined (HAVE_UNISTD_H) @@ -237,7 +239,7 @@ _netopen6 (host, serv, typ) return -1; } - for (res = res0; res; res = res->ai_next) + for (res = res0, s = -1; res; res = res->ai_next) { if ((s = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) { @@ -348,3 +350,5 @@ netopen (path) } #endif /* !HAVE_NETWORK */ + +#endif /* !NETWORK_REDIRECTIONS */ diff --git a/lib/sh/pathcanon.c b/lib/sh/pathcanon.c index 3b427a8..8f48c03 100644 --- a/lib/sh/pathcanon.c +++ b/lib/sh/pathcanon.c @@ -114,7 +114,7 @@ sh_canonpath (path, flags) /* POSIX.2 says to leave a leading `//' alone. On cygwin, we skip over any leading `x:' (dos drive name). */ - if (rooted = ROOTEDPATH(path)) + if ((rooted = ROOTEDPATH(path))) { stub_char = DIRSEP; #if defined (__CYGWIN__) diff --git a/lib/sh/spell.c b/lib/sh/spell.c index cff20b2..20fc8bb 100644 --- a/lib/sh/spell.c +++ b/lib/sh/spell.c @@ -95,7 +95,7 @@ spname(oldname, newname) /* * Add to end of newname */ - for (p = best; *np = *p++; np++) + for (p = best; (*np = *p++); np++) ; } } diff --git a/lib/sh/strtrans.c b/lib/sh/strtrans.c index 1f0290e..f4d7cdb 100644 --- a/lib/sh/strtrans.c +++ b/lib/sh/strtrans.c @@ -247,7 +247,7 @@ ansic_shouldquote (string) if (string == 0) return 0; - for (s = string; c = *s; s++) + for (s = string; (c = *s); s++) if (ISPRINT (c) == 0) return 1; diff --git a/lib/sh/tmpfile.c b/lib/sh/tmpfile.c index 5f2279d..e895ff4 100644 --- a/lib/sh/tmpfile.c +++ b/lib/sh/tmpfile.c @@ -22,132 +22,49 @@ #include -#include -#include -#include -#include #if defined (HAVE_UNISTD_H) # include #endif #include -#include +#include #include -#ifndef errno -extern int errno; -#endif - -#define BASEOPENFLAGS (O_CREAT | O_TRUNC | O_EXCL) - -#define DEFAULT_TMPDIR "." /* bogus default, should be changed */ -#define DEFAULT_NAMEROOT "shtmp" - -extern pid_t dollar_dollar_pid; - -static char *get_sys_tmpdir __P((void)); -static char *get_tmpdir __P((int)); - -static char *sys_tmpdir = (char *)NULL; -static int ntmpfiles; -static int tmpnamelen = -1; -static unsigned long filenum = 1L; - -static char * -get_sys_tmpdir () -{ - if (sys_tmpdir) - return sys_tmpdir; - -#ifdef P_tmpdir - sys_tmpdir = P_tmpdir; - if (file_iswdir (sys_tmpdir)) - return sys_tmpdir; -#endif - - sys_tmpdir = "/tmp"; - if (file_iswdir (sys_tmpdir)) - return sys_tmpdir; - - sys_tmpdir = "/var/tmp"; - if (file_iswdir (sys_tmpdir)) - return sys_tmpdir; - - sys_tmpdir = "/usr/tmp"; - if (file_iswdir (sys_tmpdir)) - return sys_tmpdir; - - sys_tmpdir = DEFAULT_TMPDIR; - - return sys_tmpdir; -} +#define DEFAULT_TMPDIR P_tmpdir +#define DEFAULT_NAMEROOT "bash" static char * get_tmpdir (flags) int flags; { - char *tdir; - - tdir = (flags & MT_USETMPDIR) ? get_string_value ("TMPDIR") : (char *)NULL; - if (tdir == 0) - tdir = get_sys_tmpdir (); - -#if defined (HAVE_PATHCONF) && defined (_PC_NAME_MAX) - if (tmpnamelen == -1) - tmpnamelen = pathconf (tdir, _PC_NAME_MAX); -#else - tmpnamelen = 0; -#endif - - return tdir; + if (flags & MT_USETMPDIR) + return get_string_value ("TMPDIR") ?: DEFAULT_TMPDIR; + return DEFAULT_TMPDIR; } +#if !defined(HAVE_DEV_FD) +/* This is renamed to *_unsafe to trap and review possible additional + * references when applying the patch to future versions of bash. */ char * -sh_mktmpname (nameroot, flags) +sh_mktmpname_unsafe (nameroot, flags) char *nameroot; int flags; { - char *filename, *tdir, *lroot; - struct stat sb; - int r, tdlen; - - filename = (char *)xmalloc (PATH_MAX + 1); - tdir = get_tmpdir (flags); - tdlen = strlen (tdir); - - lroot = nameroot ? nameroot : DEFAULT_NAMEROOT; + char *filename; -#ifdef USE_MKTEMP - sprintf (filename, "%s/%s.XXXXXX", tdir, lroot); - if (mktemp (filename) == 0) + if (asprintf (&filename, "%s/%s.XXXXXX", get_tmpdir (flags), + nameroot ?: DEFAULT_NAMEROOT) < 0) + return NULL; + if (!mktemp (filename) || !*filename) { free (filename); filename = NULL; } -#else /* !USE_MKTEMP */ - while (1) - { - filenum = (filenum << 1) ^ - (unsigned long) time ((time_t *)0) ^ - (unsigned long) dollar_dollar_pid ^ - (unsigned long) ((flags & MT_USERANDOM) ? get_random_number () : ntmpfiles++); - sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum); - if (tmpnamelen > 0 && tmpnamelen < 32) - filename[tdlen + 1 + tmpnamelen] = '\0'; -# ifdef HAVE_LSTAT - r = lstat (filename, &sb); -# else - r = stat (filename, &sb); -# endif - if (r < 0 && errno == ENOENT) - break; - } -#endif /* !USE_MKTEMP */ - return filename; } +#endif /* !defined(HAVE_DEV_FD) */ int sh_mktmpfd (nameroot, flags, namep) @@ -155,47 +72,25 @@ sh_mktmpfd (nameroot, flags, namep) int flags; char **namep; { - char *filename, *tdir, *lroot; - int fd, tdlen; - - filename = (char *)xmalloc (PATH_MAX + 1); - tdir = get_tmpdir (flags); - tdlen = strlen (tdir); + char *filename; + int fd = -1; - lroot = nameroot ? nameroot : DEFAULT_NAMEROOT; - -#ifdef USE_MKSTEMP - sprintf (filename, "%s/%s.XXXXXX", tdir, lroot); - fd = mkstemp (filename); - if (fd < 0 || namep == 0) + if (namep) + *namep = NULL; + if (asprintf (&filename, "%s/%s.XXXXXX", get_tmpdir (flags), + nameroot ?: DEFAULT_NAMEROOT) < 0) + return -1; + if ((fd = mkstemp (filename)) < 0) { free (filename); filename = NULL; } if (namep) *namep = filename; - return fd; -#else /* !USE_MKSTEMP */ - do - { - filenum = (filenum << 1) ^ - (unsigned long) time ((time_t *)0) ^ - (unsigned long) dollar_dollar_pid ^ - (unsigned long) ((flags & MT_USERANDOM) ? get_random_number () : ntmpfiles++); - sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum); - if (tmpnamelen > 0 && tmpnamelen < 32) - filename[tdlen + 1 + tmpnamelen] = '\0'; - fd = open (filename, BASEOPENFLAGS | ((flags & MT_READWRITE) ? O_RDWR : O_WRONLY), 0600); - } - while (fd < 0 && errno == EEXIST); - - if (namep) - *namep = filename; - else - free (filename); + else if (filename) + free(filename); return fd; -#endif /* !USE_MKSTEMP */ } FILE * @@ -207,9 +102,8 @@ sh_mktmpfp (nameroot, flags, namep) int fd; FILE *fp; - fd = sh_mktmpfd (nameroot, flags, namep); - if (fd < 0) - return ((FILE *)NULL); + if ((fd = sh_mktmpfd (nameroot, flags, namep)) < 0) + return NULL; fp = fdopen (fd, (flags & MT_READWRITE) ? "w+" : "w"); if (fp == 0) close (fd); diff --git a/lib/sh/winsize.c b/lib/sh/winsize.c index f4696de..9ec2959 100644 --- a/lib/sh/winsize.c +++ b/lib/sh/winsize.c @@ -23,6 +23,8 @@ #include #include "bashtypes.h" +#include "shell.h" +#include "variables.h" #if defined (HAVE_UNISTD_H) # include diff --git a/lib/tilde/tilde.c b/lib/tilde/tilde.c index 1b76c9f..b59b502 100644 --- a/lib/tilde/tilde.c +++ b/lib/tilde/tilde.c @@ -196,7 +196,7 @@ tilde_expand (string) int result_size, result_index; result_index = result_size = 0; - if (result = strchr (string, '~')) + if ((result = strchr (string, '~'))) result = (char *)xmalloc (result_size = (strlen (string) + 16)); else result = (char *)xmalloc (result_size = (strlen (string) + 1)); diff --git a/mailcheck.c b/mailcheck.c index 4b7e207..44290cf 100644 --- a/mailcheck.c +++ b/mailcheck.c @@ -338,7 +338,7 @@ remember_mail_dates () return; } - while (mailfile = extract_colon_unit (mailpaths, &i)) + while ((mailfile = extract_colon_unit (mailpaths, &i))) { mp = parse_mailpath_spec (mailfile); if (mp && *mp) @@ -412,7 +412,7 @@ check_mail () #undef atime #undef mtime - if (temp = expand_string_to_string (message, Q_DOUBLE_QUOTES)) + if ((temp = expand_string_to_string (message, Q_DOUBLE_QUOTES))) { puts (temp); free (temp); diff --git a/make_cmd.c b/make_cmd.c index a8448d5..c819b27 100644 --- a/make_cmd.c +++ b/make_cmd.c @@ -41,11 +41,15 @@ Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #include "flags.h" #include "make_cmd.h" #include "dispose_cmd.h" +#include "execute_cmd.h" #include "variables.h" #include "subst.h" #include "input.h" #include "ocache.h" #include "externs.h" +#include "builtins.h" + +#include "builtins/common.h" #if defined (JOB_CONTROL) #include "jobs.h" @@ -55,6 +59,10 @@ Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ extern int line_number, current_command_line_count; extern int last_command_exit_value; +extern int rpm_requires; + +static char *alphabet_set = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; /* Object caching */ sh_obj_cache_t wdcache = {0, 0, 0}; @@ -602,7 +610,7 @@ make_here_document (temp) be read verbatim from the input. If it was not quoted, we need to perform backslash-quoted newline removal. */ delim_unquoted = (temp->redirectee.filename->flags & W_QUOTED) == 0; - while (full_line = read_secondary_line (delim_unquoted)) + while ((full_line = read_secondary_line (delim_unquoted))) { register char *line; int len; @@ -746,6 +754,27 @@ make_redirection (source, instruction, dest_and_filename) return (temp); } +static void +output_requirement (deptype, filename) +const char *deptype; +char *filename; +{ + if (strchr(filename, '$') || (filename[0] != '/' && strchr(filename, '/'))) + return; + + /* + if the executable is called via variable substitution we can + not dermine what it is at compile time. + + if the executable consists only of characters not in the + alphabet we do not consider it a dependency just an artifact + of shell parsing (ex "exec < ${infile}"). + */ + + if (strpbrk(filename, alphabet_set)) + printf ("%s(%s)\n", deptype, filename); +} + COMMAND * make_function_def (name, command, lineno, lstart) WORD_DESC *name; @@ -774,6 +803,23 @@ make_function_def (name, command, lineno, lstart) #endif bind_function_def (name->word, temp); + if (rpm_requires) + /* Each function is possibly required, which is, er, provided. + * I need to know function names in order to implement strong + * self-requires elimination in /usr/lib/rpm/shell.req. Just about + * the only way to achieve this without breaking "--rpm-requires" + * compatibility is to spit them here as they go. + * + * Also note that another "function" output in clean_simple_command() + * is not much useful since it only means that a function is defined + * in the very same file before being used (shell have seen it while + * parsing the script). My point is that it makes no sense to resolve + * function requirements -- functions are simply "provided" by its nature. + * + * -- at@altlinux + */ + output_requirement ("function", name->word); + temp->source_file = 0; return (make_command (cm_function_def, (SIMPLE_COM *)temp)); } @@ -807,6 +853,43 @@ clean_simple_command (command) REVERSE_LIST (command->value.Simple->redirects, REDIRECT *); } + if (rpm_requires && command->value.Simple->words) + { + WORD_LIST *words = command->value.Simple->words; + const char *cmd = words->word->word; + + /* skip LC_* assignments */ + while (words->next && assignment (cmd, 0)) + { + if (strncmp (cmd, "LC_", 3) != 0) + break; + words = words->next; + cmd = words->word->word; + } + + if (!assignment (cmd, 0)) + { + struct builtin *b = builtin_address_internal (cmd, 0); + if (b) + { + /* exec-like builtin with an argument */ + if ((b->flags & REQUIRES_BUILTIN) && words->next) + { + words = words->next; + cmd = words->word->word; + output_requirement ("executable", cmd); + } + } + else + { + if (find_function (cmd) || find_function_def (cmd)) + output_requirement ("function", cmd); + else + output_requirement ("executable", cmd); + } + } + } /* rpm_requires */ + return (command); } diff --git a/parse.y b/parse.y index f1967ab..004df4a 100644 --- a/parse.y +++ b/parse.y @@ -194,7 +194,9 @@ static int token_is_assignment __P((char *, int)); static int token_is_ident __P((char *, int)); #endif static int read_token_word __P((int)); +#ifdef INCLUDE_UNUSED static void discard_parser_constructs __P((int)); +#endif static char *error_token_from_token __P((int)); static char *error_token_from_text __P((void)); @@ -2778,6 +2780,7 @@ parse_matched_pair (qc, open, close, lenp, flags) rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE); ret = (char *)xmalloc (retsize = 64); + nestret = NULL; retind = 0; start_lineno = line_number; @@ -3103,7 +3106,7 @@ cond_error () parser_error (cond_lineno, _("unexpected EOF while looking for `]]'")); else if (cond_token != COND_ERROR) { - if (etext = error_token_from_token (cond_token)) + if ((etext = error_token_from_token (cond_token))) { parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext); free (etext); @@ -3185,7 +3188,7 @@ cond_term () { if (term) dispose_cond_node (term); /* ( */ - if (etext = error_token_from_token (cond_token)) + if ((etext = error_token_from_token (cond_token))) { parser_error (lineno, _("unexpected token `%s', expected `)'"), etext); free (etext); @@ -3217,7 +3220,7 @@ cond_term () else { dispose_word (op); - if (etext = error_token_from_token (tok)) + if ((etext = error_token_from_token (tok))) { parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext); free (etext); @@ -3261,7 +3264,7 @@ cond_term () } else { - if (etext = error_token_from_token (tok)) + if ((etext = error_token_from_token (tok))) { parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext); free (etext); @@ -3282,7 +3285,7 @@ cond_term () } else { - if (etext = error_token_from_token (tok)) + if ((etext = error_token_from_token (tok))) { parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext); free (etext); @@ -3300,7 +3303,7 @@ cond_term () { if (tok < 256) parser_error (line_number, _("unexpected token `%c' in conditional command"), tok); - else if (etext = error_token_from_token (tok)) + else if ((etext = error_token_from_token (tok))) { parser_error (line_number, _("unexpected token `%s' in conditional command"), etext); free (etext); @@ -4061,7 +4064,10 @@ decode_prompt_string (string) int last_exit_value; #if defined (PROMPT_STRING_DECODE) int result_size, result_index; - int c, n, i; + int c, n; +#if defined (READLINE) + int i; +#endif /* READLINE */ char *temp, octal_string[4]; struct tm *tm; time_t the_time; @@ -4071,8 +4077,9 @@ decode_prompt_string (string) result = (char *)xmalloc (result_size = PROMPT_GROWTH); result[result_index = 0] = 0; temp = (char *)NULL; + n = 0; - while (c = *string++) + while ((c = *string++)) { if (posixly_correct && c == '!') { @@ -4439,10 +4446,10 @@ error_token_from_token (tok) { char *t; - if (t = find_token_in_alist (tok, word_token_alist, 0)) + if ((t = find_token_in_alist (tok, word_token_alist, 0))) return t; - if (t = find_token_in_alist (tok, other_token_alist, 0)) + if ((t = find_token_in_alist (tok, other_token_alist, 0))) return t; t = (char *)NULL; @@ -4594,6 +4601,7 @@ report_syntax_error (message) last_command_exit_value = EX_USAGE; } +#ifdef INCLUDE_UNUSED /* ??? Needed function. ??? We have to be able to discard the constructs created during parsing. In the case of error, we want to return allocated objects to the memory pool. In the case of no error, we want @@ -4604,6 +4612,7 @@ discard_parser_constructs (error_p) int error_p; { } +#endif /************************************************ * * diff --git a/pathexp.c b/pathexp.c index 69966ac..9052d41 100644 --- a/pathexp.c +++ b/pathexp.c @@ -67,7 +67,7 @@ unquoted_glob_pattern_p (string) open = 0; send = string + strlen (string); - while (c = *string++) + while ((c = *string++)) { switch (c) { @@ -448,7 +448,7 @@ setup_ignore_patterns (ivp) numitems = maxitems = ptr = 0; - while (colon_bit = extract_colon_unit (this_ignoreval, &ptr)) + while ((colon_bit = extract_colon_unit (this_ignoreval, &ptr))) { if (numitems + 1 >= maxitems) { diff --git a/pcomplete.c b/pcomplete.c index 471fb54..04b348a 100644 --- a/pcomplete.c +++ b/pcomplete.c @@ -520,6 +520,8 @@ it_init_joblist (itp, jstate) ws = JRUNNING; else if (jstate == 1) ws = JSTOPPED; + else + ws = -1; sl = strlist_create (js.j_jobslots); for (i = js.j_jobslots - 1; i >= 0; i--) diff --git a/print_cmd.c b/print_cmd.c index d1dfd1a..956db53 100644 --- a/print_cmd.c +++ b/print_cmd.c @@ -1149,7 +1149,7 @@ indent (amount) for (i = 0; amount > 0; amount--) indentation_string[i++] = ' '; indentation_string[i] = '\0'; - cprintf (indentation_string); + cprintf ("%s", indentation_string); } static void diff --git a/redir.c b/redir.c index 0bd2d5f..de847f7 100644 --- a/redir.c +++ b/redir.c @@ -93,6 +93,7 @@ redirection_error (temp, error) int oflags; allocname = 0; + oflags = 0; if (temp->redirector < 0) /* This can happen when read_token_word encounters overflow, like in exec 4294967297>x */ @@ -375,7 +376,7 @@ here_document_to_fd (redirectee, ri) char *filename; int r, fd, fd2; - fd = sh_mktmpfd ("sh-thd", MT_USERANDOM, &filename); + fd = sh_mktmpfd ("sh-thd", MT_USETMPDIR, &filename); /* If we failed for some reason other than the file existing, abort */ if (fd < 0) @@ -629,6 +630,7 @@ do_redirection_internal (redirect, flags) redir_fd = redirect->redirectee.dest; redirector = redirect->redirector; ri = redirect->instruction; + oflags = 0; if (redirect->flags & RX_INTERNAL) flags |= RX_INTERNAL; @@ -638,6 +640,7 @@ do_redirection_internal (redirect, flags) /* We have [N]>&WORD[-] or [N]<&WORD[-]. Expand WORD, then translate the redirection into a new one and continue. */ redirectee_word = redirection_expand (redirectee); + new_redirect = NULL; /* XXX - what to do with [N]<&$w- where w is unset or null? ksh93 closes N. */ @@ -668,6 +671,8 @@ do_redirection_internal (redirect, flags) case r_move_output_word: new_redirect = make_redirection (redirector, r_move_output, rd); break; + default: + break; } } else if (ri == r_duplicating_output_word && redirector == 1) @@ -938,6 +943,7 @@ do_redirection_internal (redirect, flags) case r_duplicating_input_word: case r_duplicating_output_word: + default: break; } return (0); @@ -1066,9 +1072,9 @@ stdin_redirection (ri, redirector) case r_err_and_out: case r_output_force: case r_duplicating_output_word: + default: return (0); } - return (0); } /* Return non-zero if any of the redirections in REDIRS alter the standard diff --git a/shell.c b/shell.c index 6693f85..04643fb 100644 --- a/shell.c +++ b/shell.c @@ -175,6 +175,9 @@ int running_under_emacs; /* The name of the .(shell)rc file. */ static char *bashrc_file = "~/.bashrc"; +/* Non-zero if we are finding the scripts requirements. */ +int rpm_requires; + /* Non-zero means to act more like the Bourne shell on startup. */ static int act_like_sh; @@ -233,6 +236,7 @@ struct { { "posix", Int, &posixly_correct, (char **)0x0 }, { "protected", Int, &protected_mode, (char **)0x0 }, { "rcfile", Charp, (int *)0x0, &bashrc_file }, + { "rpm-requires", Int, &rpm_requires, (char **)0x0 }, #if defined (RESTRICTED_SHELL) { "restricted", Int, &restricted, (char **)0x0 }, #endif @@ -460,6 +464,12 @@ main (argc, argv, env) if (dump_translatable_strings) read_but_dont_execute = 1; + if (rpm_requires) + { + read_but_dont_execute = 1; + initialize_shell_builtins (); + } + if (running_setuid && privileged_mode == 0) disable_priv_mode (); @@ -797,7 +807,7 @@ parse_shell_options (argv, arg_start, arg_end) i = 1; on_or_off = arg_string[0]; - while (arg_character = arg_string[i++]) + while ((arg_character = arg_string[i++])) { switch (arg_character) { @@ -1541,7 +1551,7 @@ set_shell_name (argv0) login_shell++; } - if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0') + if (shell_name[0] == 's' && shell_name[1] == 'h' && (shell_name[2] == '\0' || (shell_name[2] == '3' && shell_name[3] == '\0'))) act_like_sh++; if (shell_name[0] == 's' && shell_name[1] == 'u' && shell_name[2] == '\0') su_shell++; diff --git a/sig.c b/sig.c index c479a4a..ea66f94 100644 --- a/sig.c +++ b/sig.c @@ -308,8 +308,9 @@ initialize_shell_signals () { set_signal_handler (SIGINT, sigint_sighandler); set_signal_handler (SIGTERM, SIG_IGN); - set_sigwinch_handler (); } + + set_sigwinch_handler (); } void diff --git a/subst.c b/subst.c index 089457f..c530c79 100644 --- a/subst.c +++ b/subst.c @@ -50,6 +50,8 @@ #include "shmbutil.h" +#include "sig.h" + #include "builtins/getopt.h" #include "builtins/common.h" @@ -190,8 +192,10 @@ WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL; without any leading variable assignments. */ static WORD_LIST *garglist = (WORD_LIST *)NULL; +#ifdef INCLUDE_UNUSED static char *quoted_substring __P((char *, int, int)); static int quoted_strlen __P((char *)); +#endif static char *quoted_strchr __P((char *, int, int)); static char *expand_string_if_necessary __P((char *, int, EXPFUNC *)); @@ -208,8 +212,10 @@ static WORD_LIST *quote_list __P((WORD_LIST *)); static char *remove_quoted_escapes __P((char *)); static char *remove_quoted_nulls __P((char *)); +#ifdef INCLUDE_UNUSED static int unquoted_substring __P((char *, char *)); static int unquoted_member __P((int, char *)); +#endif #if defined (ARRAY_VARS) static SHELL_VAR *do_compound_assignment __P((char *, char *, int)); @@ -227,7 +233,9 @@ static char *extract_dollar_brace_string __P((char *, int *, int, int)); static char *pos_params __P((char *, int, int, int)); +#ifdef INCLUDE_UNUSED static unsigned char *mb_getcharlens __P((char *, int)); +#endif static char *remove_upattern __P((char *, char *, int)); #if defined (HANDLE_MULTIBYTE) @@ -244,7 +252,9 @@ static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char static int match_pattern __P((char *, char *, int, char **, char **)); static int getpatspec __P((int, char *)); static char *getpattern __P((char *, int, int)); +#ifdef INCLUDE_UNUSED static char *variable_remove_pattern __P((char *, char *, int, int)); +#endif static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int)); static char *parameter_list_remove_pattern __P((int, char *, int, int)); #ifdef ARRAY_VARS @@ -289,7 +299,7 @@ static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *) static WORD_LIST *word_list_split __P((WORD_LIST *)); -static void exp_jump_to_top_level __P((int)); +static void exp_jump_to_top_level __P((int)) __attribute__((__noreturn__)); static WORD_LIST *separate_out_assignments __P((WORD_LIST *)); static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int)); @@ -399,6 +409,7 @@ quoted_strchr (s, c, flags) return ((char *)NULL); } +#ifdef INCLUDE_UNUSED /* Return 1 if CHARACTER appears in an unquoted portion of STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */ static int @@ -412,7 +423,7 @@ unquoted_member (character, string) slen = strlen (string); sindex = 0; - while (c = string[sindex]) + while ((c = string[sindex])) { if (c == character) return (1); @@ -440,7 +451,9 @@ unquoted_member (character, string) } return (0); } +#endif +#ifdef INCLUDE_UNUSED /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */ static int unquoted_substring (substr, string) @@ -455,7 +468,7 @@ unquoted_substring (substr, string) slen = strlen (string); sublen = strlen (substr); - for (sindex = 0; c = string[sindex]; ) + for (sindex = 0; (c = string[sindex]); ) { if (STREQN (string + sindex, substr, sublen)) return (1); @@ -484,6 +497,7 @@ unquoted_substring (substr, string) } return (0); } +#endif /* Most of the substitutions must be done in parallel. In order to avoid using tons of unclear goto's, I have some functions @@ -565,7 +579,7 @@ string_extract (string, sindex, charlist, flags) slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0; i = *sindex; found = 0; - while (c = string[i]) + while ((c = string[i])) { if (c == '\\') { @@ -636,7 +650,7 @@ string_extract_double_quoted (string, sindex, stripdq) j = 0; i = *sindex; - while (c = string[i]) + while ((c = string[i])) { /* Process a character that was quoted by a backslash. */ if (pass_next) @@ -783,7 +797,7 @@ skip_double_quoted (string, slen, sind) pass_next = backquote = 0; i = sind; - while (c = string[i]) + while ((c = string[i])) { if (pass_next) { @@ -918,7 +932,7 @@ string_extract_verbatim (string, slen, sindex, charlist) clen = strlen (charlist); wcharlist = 0; #endif - while (c = string[i]) + while ((c = string[i])) { #if defined (HANDLE_MULTIBYTE) size_t mblength; @@ -1206,7 +1220,7 @@ extract_dollar_brace_string (string, sindex, quoted, flags) slen = strlen (string + *sindex) + *sindex; i = *sindex; - while (c = string[i]) + while ((c = string[i])) { if (pass_character) { @@ -1475,7 +1489,7 @@ skip_to_delim (string, start, delims) no_longjmp_on_fatal_error = 1; i = start; pass_next = backq = 0; - while (c = string[i]) + while ((c = string[i])) { if (pass_next) { @@ -1956,6 +1970,7 @@ list_string (string, separators, quoted) separators[3] == '\0'; slen = 0; + s = NULL; /* Remove sequences of whitespace at the beginning of STRING, as long as those characters appear in IFS. Do not do this if STRING is quoted or if there are no separator characters. */ @@ -2327,7 +2342,7 @@ do_assignment_internal (word, expand) aflags |= ASS_APPEND; #if defined (ARRAY_VARS) - if (t = xstrchr (name, '[')) /*]*/ + if ((t = xstrchr (name, '['))) /*]*/ { if (assign_list) { @@ -4158,13 +4173,24 @@ static char * make_named_pipe () { char *tname; + int retries; - tname = sh_mktmpname ("sh-np", MT_USERANDOM); - if (mkfifo (tname, 0600) < 0) + retries = 0x1000; + do { - free (tname); - return ((char *)NULL); - } + tname = sh_mktmpname_unsafe ("sh-np", MT_USETMPDIR); + if (!tname) + { + free (tname); + return ((char *)NULL); + } + if (mkfifo (tname, 0600) == 0) break; + if (errno != EEXIST || !--retries) + { + free (tname); + return ((char *)NULL); + } + } while(1); add_fifo_list (tname); return (tname); @@ -4463,6 +4489,7 @@ read_comsub (fd, quoted) istring = (char *)NULL; istring_index = istring_size = bufn = 0; + bufp = NULL; #ifdef __CYGWIN__ setmode (fd, O_TEXT); /* we don't want CR/LF, we want Unix-style */ @@ -4950,7 +4977,7 @@ parameter_brace_expand_word (name, var_is_special, quoted) rflags |= W_HASQUOTEDNULL; } #endif - else if (var = find_variable (name)) + else if ((var = find_variable (name))) { if (var_isset (var) && invisible_p (var) == 0) { @@ -5188,6 +5215,7 @@ parameter_brace_expand_length (name) number = number_of_args (); else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') { + t = NULL; /* Take the lengths of some of the shell's special parameters. */ switch (name[1]) { @@ -5345,6 +5373,7 @@ verify_substring_values (value, substr, vtype, e1p, e2p) return (0); len = -1; /* paranoia */ + a = NULL; switch (vtype) { case VT_VARIABLE: @@ -5782,10 +5811,8 @@ parameter_brace_patsub (varname, value, patsub, quoted) /* If the pattern starts with a `/', make sure we skip over it when looking for the replacement delimiter. */ - if (rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL)) + if ((rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL))) *rep++ = '\0'; - else - rep = (char *)NULL; if (rep && *rep == '\0') rep = (char *)NULL; @@ -5833,6 +5860,7 @@ parameter_brace_patsub (varname, value, patsub, quoted) other cases if QUOTED == 0, since the posparams and arrays indexed by * or @ do special things when QUOTED != 0. */ + temp = NULL; switch (vtype) { case VT_VARIABLE: @@ -5997,7 +6025,7 @@ parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_doll /* Find out what character ended the variable name. Then do the appropriate thing. */ - if (c = string[sindex]) + if ((c = string[sindex])) sindex++; /* If c is followed by one of the valid parameter expansion @@ -6007,7 +6035,7 @@ parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_doll if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex])) { check_nullness++; - if (c = string[sindex]) + if ((c = string[sindex])) sindex++; } else if (c == ':' && string[sindex] != RBRACE) @@ -6200,6 +6228,15 @@ parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_doll *indexp = sindex; /* If this is a substring spec, process it and add the result. */ + if ((want_substring || want_patsub) && var_is_set == 0 && unbound_vars_is_error) + { + err_unboundvar (name); + FREE (value); + FREE (temp); + free (name); + last_command_exit_value = EXECUTION_FAILURE; + return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); + } if (want_substring) { temp1 = parameter_brace_substring (name, temp, value, quoted); @@ -6261,6 +6298,15 @@ parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_doll case '#': /* ${param#[#]pattern} */ case '%': /* ${param%[%]pattern} */ + if (var_is_set == 0 && unbound_vars_is_error) + { + err_unboundvar (name); + FREE (value); + FREE (temp); + free (name); + last_command_exit_value = EXECUTION_FAILURE; + return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); + } if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0') { FREE (value); @@ -7461,7 +7507,7 @@ string_quote_removal (string, quoted) r = result_string = (char *)xmalloc (slen + 1); - for (dquote = sindex = 0; c = string[sindex];) + for (dquote = sindex = 0; (c = string[sindex]);) { switch (c) { @@ -7642,7 +7688,7 @@ word_list_split (list) { WORD_LIST *result, *t, *tresult, *e; - for (t = list, result = (WORD_LIST *)NULL; t; t = t->next) + for (t = list, result = e = (WORD_LIST *)NULL; t; t = t->next) { tresult = word_split (t->word, ifs_value); if (result == 0) @@ -7957,7 +8003,7 @@ brace_expand_word_list (tlist, eflags) { expansions = brace_expand (tlist->word->word); - for (eindex = 0; temp_string = expansions[eindex]; eindex++) + for (eindex = 0; (temp_string = expansions[eindex]); eindex++) { w = make_word (temp_string); /* If brace expansion didn't change the word, preserve diff --git a/support/bashbug.sh b/support/bashbug.sh index 8c4e1ec..f365074 100644 --- a/support/bashbug.sh +++ b/support/bashbug.sh @@ -1,4 +1,4 @@ -#!/bin/sh - +#!/bin/sh3 - # # bashbug - create a bug report and mail it to the bug address # @@ -39,18 +39,14 @@ MACHTYPE="!MACHTYPE!" PATH=/bin:/usr/bin:/usr/local/bin:$PATH export PATH -# Check if TMPDIR is set, default to /tmp -: ${TMPDIR:=/tmp} - -#Securely create a temporary directory for the temporary files -TEMPDIR=$TMPDIR/bbug.$$ -(umask 077 && mkdir $TEMPDIR) || { - echo "$0: could not create temporary directory" >&2 +TEMPFILE1="`mktemp -t bashbug.XXXXXXXXXX`" || exit 1 +TEMPFILE2="`mktemp -t bashbug.XXXXXXXXXX`" || { + rm -f "$TEMPFILE1" exit 1 } -TEMPFILE1=$TEMPDIR/bbug1 -TEMPFILE2=$TEMPDIR/bbug2 +trap 'rm -f "$TEMPFILE1" "$TEMPFILE2"; exit 1' HUP INT PIPE TERM +trap 'rm -f "$TEMPFILE1" "$TEMPFILE2"' EXIT USAGE="Usage: $0 [--help] [--version] [bug-report-email-address]" VERSTR="GNU bashbug, version ${RELEASE}.${PATCHLEVEL}-${RELSTATUS}" @@ -121,24 +117,8 @@ esac BUGADDR="${1-$BUGBASH}" if [ -z "$DEFEDITOR" ] && [ -z "$EDITOR" ]; then - if [ -x /usr/bin/editor ]; then - DEFEDITOR=editor - elif [ -x /usr/local/bin/ce ]; then - DEFEDITOR=ce - elif [ -x /usr/local/bin/emacs ]; then - DEFEDITOR=emacs - elif [ -x /usr/contrib/bin/emacs ]; then - DEFEDITOR=emacs - elif [ -x /usr/bin/emacs ]; then - DEFEDITOR=emacs - elif [ -x /usr/bin/xemacs ]; then - DEFEDITOR=xemacs - elif [ -x /usr/contrib/bin/jove ]; then - DEFEDITOR=jove - elif [ -x /usr/local/bin/jove ]; then - DEFEDITOR=jove - elif [ -x /usr/bin/vi ]; then - DEFEDITOR=vi + if [ -x /bin/vitmp ]; then + DEFEDITOR=vitmp else echo "$0: No default editor found: attempting to use vi" >&2 DEFEDITOR=vi @@ -150,9 +130,6 @@ fi : ${USER=${LOGNAME-`whoami`}} -trap 'rm -rf "$TEMPDIR"; exit 1' 1 2 3 13 15 -trap 'rm -rf "$TEMPDIR"' 0 - UN= if (uname) >/dev/null 2>&1; then UN=`uname -a` @@ -203,7 +180,8 @@ EOF cp "$TEMPFILE1" "$TEMPFILE2" chmod u+w "$TEMPFILE1" -trap '' 2 # ignore interrupts while in editor +# ignore interrupts while in editor +trap '' INT edstat=1 while [ $edstat -ne 0 ]; do @@ -250,7 +228,8 @@ while [ $edstat -ne 0 ]; do done -trap 'rm -rf "$TEMPDIR"; exit 1' 2 # restore trap on SIGINT +# restore trap on SIGINT +trap 'rm -f "$TEMPFILE1" "$TEMPFILE2"; exit 1' INT if cmp -s "$TEMPFILE1" "$TEMPFILE2" then diff --git a/support/fixlinks b/support/fixlinks index 13a86c8..a40be68 100755 --- a/support/fixlinks +++ b/support/fixlinks @@ -22,7 +22,7 @@ SRCDIR=. while [ $# -gt 0 ]; do case "$1" in - -s) shift; SRCDIR=$1 ;; + -s) shift; SRCDIR="$1" ;; -u) unfix=yes ;; -h) hardlinks=yes ;; -*) echo "$0: $1: bad option" 1>&2 @@ -33,15 +33,15 @@ while [ $# -gt 0 ]; do shift done -if [ ! -d $SRCDIR/builtins ]; then +if [ ! -d "$SRCDIR/builtins" ]; then echo "$0: must be run with valid -s argument or from source directory" 1>&2 exit 1 fi if [ $# -eq 0 ]; then - linkfile=$SRCDIR/support/SYMLINKS + linkfile="$SRCDIR/support/SYMLINKS" else - linkfile=$1 + linkfile="$1" fi if [ ! -f "$linkfile" ]; then @@ -49,25 +49,12 @@ if [ ! -f "$linkfile" ]; then exit 1 fi -rm_ltmp=false -LINKTEMP=`mktemp -t linktmp.XXXXXXXX 2>/dev/null` -if [ -z "$LINKTEMP" ]; then - : ${TMPDIR:=/tmp} - LINKTEMP=${TMPDIR}/linktmp.$$ - rm_ltmp=true -fi - -$rm_ltmp && rm -f ${LINKTEMP} -# if the user specified hard links, then do that. otherwise, try to use -# symlinks if they're present +# if the user specified hard links, then do that. otherwise, use symlinks. if [ -n "$hardlinks" ]; then LN=ln -elif (ln -s /dev/null ${LINKTEMP}) >/dev/null 2>&1; then - LN="ln -s" else - LN=ln + LN="ln -s" fi -rm -f ${LINKTEMP} while read name target do @@ -75,15 +62,15 @@ do \#*) continue;; esac - rm -f $name + rm -f "$name" case "$unfix" in yes) dirname=`expr "$name" ':' '^\(.*\)/[^/]*'` [ -z "$dirname" ] && dirname=. - cp $dirname/$target $name - echo $target copied to $name ;; - *) $LN $target $name ; echo "$name -> $target" ;; + cp "$dirname/$target" "$name" + echo "$target copied to $name" ;; + *) $LN "$target" "$name" ; echo "$name -> $target" ;; esac -done < $linkfile +done < "$linkfile" exit 0 diff --git a/support/man2html.c b/support/man2html.c index 2432c13..fafb266 100644 --- a/support/man2html.c +++ b/support/man2html.c @@ -279,7 +279,7 @@ struct INTDEF { static char NEWLINE[2] = "\n"; static char idxlabel[6] = "ixAAA"; -#define INDEXFILE "/tmp/manindex.list" +#define INDEXFILE "manindex.list" static char *fname; static FILE *idxfile; diff --git a/support/mkclone b/support/mkclone index 10b08c0..5ed059b 100755 --- a/support/mkclone +++ b/support/mkclone @@ -28,12 +28,12 @@ USAGE="usage: $prog [-m manifest] [-s srcdir] [-v] [-d] [-h] target" while getopts dhm:s:v opt do case "$opt" in - m) MANIFEST=$OPTARG ;; - s) SRCDIR=$OPTARG ;; + m) MANIFEST="$OPTARG" ;; + s) SRCDIR="$OPTARG" ;; v) verbose=y ;; d) ECHO=echo debug=y ;; h) hardlinks=y ;; - ?) echo $USAGE >&2 + ?) echo "$USAGE" >&2 exit 2;; esac done @@ -45,37 +45,24 @@ done shift $(( $OPTIND - 1 )) if [ $# -lt 1 ]; then - echo $USAGE >&2 + echo "$USAGE" >&2 exit 2 fi -if [ ! -f $MANIFEST ]; then +if [ ! -f "$MANIFEST" ]; then echo "$prog: $MANIFEST: no such file or directory" >&2 echo "$prog: must be run with valid -s argument or from source directory" >&2 exit 1 fi -rm_ltmp=false -LINKTEMP=`mktemp -t linktmp.XXXXXXXX 2>/dev/null` -if [ -z "$LINKTEMP" ]; then - : ${TMPDIR:=/tmp} - LINKTEMP=${TMPDIR}/linktmp.$$ - rm_ltmp=true -fi - -$rm_ltmp && rm -f ${LINKTEMP} -# if the user specified hard links, then do that. otherwise, try to use -# symlinks if they're present +# if the user specified hard links, then do that. otherwise, use symlinks. if [ -n "$hardlinks" ]; then LN=ln -elif (ln -s /dev/null ${LINKTEMP}) >/dev/null 2>&1; then - LN="ln -s" else - LN=ln + LN="ln -s" fi -rm -f ${LINKTEMP} -TARGET=$1 +TARGET="$1" if [ ! -d "$TARGET" ]; then mkdir "$TARGET" @@ -95,7 +82,7 @@ do case "$type" in d) [ -n "$verbose" ] && echo mkdir $fname - $ECHO mkdir $fname ;; # already in $TARGET + $ECHO mkdir "$fname" ;; # already in $TARGET f) fn=${fname##*/} case "$fname" in */*) dn=${fname%/*} ;; @@ -104,11 +91,11 @@ do if [ -n "$verbose" ] || [ -n "$debug" ]; then echo "( cd $dn && $LN $SRCDIR/$fname $fn )" fi - [ -z "$debug" ] && ( cd $dn && $LN $SRCDIR/$fname $fn ) + [ -z "$debug" ] && ( cd "$dn" && $LN "$SRCDIR/$fname" "$fn" ) ;; *) echo "${prog}: ${fname}: unknown file type $type" 1>&2 ;; esac -done < $MANIFEST +done < "$MANIFEST" # special SPECIAL="parser-built y.tab.c y.tab.h" @@ -116,8 +103,8 @@ SPECIAL="parser-built y.tab.c y.tab.h" rm -f $SPECIAL for sf in $SPECIAL do - [ -n "$verbose" ] && echo cp -p $SRCDIR/$sf $TARGET - $ECHO cp -p $SRCDIR/$sf $TARGET + [ -n "$verbose" ] && echo cp -p "$SRCDIR/$sf" "$TARGET" + $ECHO "cp -p $SRCDIR/$sf $TARGET" done exit 0 diff --git a/support/rlvers.sh b/support/rlvers.sh index b3de8fe..0468498 100755 --- a/support/rlvers.sh +++ b/support/rlvers.sh @@ -22,9 +22,6 @@ PROGNAME=`basename $0` -: ${TMPDIR:=/tmp} -TDIR=$TMPDIR/rlvers - # defaults CC=cc RL_LIBDIR=/usr/local/lib @@ -47,11 +44,11 @@ done # if someone happened to install examples/rlversion, use it (it's not # installed by default) -if test -f ${RL_LIBDIR}/rlversion ; then +if test -f "${RL_LIBDIR}/rlversion" ; then if [ -n "$verbose" ]; then echo "${PROGNAME}: using installed rlversion from ${RL_LIBDIR}/rlversion" fi - v=`${RL_LIBDIR}/rlversion 2>/dev/null` + v="`${RL_LIBDIR}/rlversion 2>/dev/null`" case "$v" in unknown | "") echo 0 ;; *) echo "$v" ;; @@ -64,17 +61,14 @@ if [ -n "$verbose" ]; then echo "${PROGNAME}: attempting program compilation" fi -# make $TDIR mode 0700 -mkdir $TDIR || { - echo "${PROGNAME}: ${TDIR}: file exists" >&2 +TDIR="mktemp -td rlvers.XXXXXXXXXX" || { echo 0 exit 1 } -chmod 700 $TDIR -trap 'rm -f $TDIR/rlvers $TDIR/rlvers.? ; rmdir $TDIR' 0 1 2 3 6 15 +trap 'rm -f "$TDIR"/rlvers "$TDIR"/rlvers.? ; rmdir "$TDIR'" EXIT HUP INT TERM -cat > $TDIR/rlvers.c << EOF +cat > "$TDIR"/rlvers.c << EOF #include extern char *rl_library_version; @@ -87,15 +81,15 @@ EOF opwd=`pwd` -cd $TDIR || { +cd "$TDIR" || { echo "${PROGNAME}: cannot cd to $TDIR" >&2 echo 0 exit 1 } -if eval ${CC} -L${RL_LIBDIR} -I${RL_INCDIR} -o $TDIR/rlvers $TDIR/rlvers.c -lreadline ${TERMCAP_LIB}; +if eval ${CC} -L${RL_LIBDIR} -I${RL_INCDIR} -o "$TDIR"/rlvers "$TDIR"/rlvers.c -lreadline ${TERMCAP_LIB}; then - v=`$TDIR/rlvers` + v=`"$TDIR"/rlvers` else if [ -n "$verbose" ] ; then echo "${PROGNAME}: compilation failed: status $?" @@ -109,5 +103,5 @@ unknown | "") echo 0 ;; *) echo "$v" ;; esac -cd $opwd +cd "$opwd" exit 0 diff --git a/trap.c b/trap.c index 2d5934f..518c92d 100644 --- a/trap.c +++ b/trap.c @@ -67,8 +67,6 @@ static int sigmodes[BASH_NSIG]; static void free_trap_command __P((int)); static void change_signal __P((int, char *)); -static void get_original_signal __P((int)); - static int _run_trap_internal __P((int, char *)); static void reset_signal __P((int)); @@ -543,15 +541,6 @@ change_signal (sig, value) sigmodes[sig] |= SIG_CHANGED; } -static void -get_original_signal (sig) - int sig; -{ - /* If we aren't sure the of the original value, then get it. */ - if (original_signals[sig] == (SigHandler *)IMPOSSIBLE_TRAP_HANDLER) - GETORIGSIG (sig); -} - /* Restore the default action for SIG; i.e., the action the shell would have taken before you used the trap command. This is called from trap_builtin (), which takes care to restore the handlers for diff --git a/unwind_prot.c b/unwind_prot.c index 4fd194e..60d4b77 100644 --- a/unwind_prot.c +++ b/unwind_prot.c @@ -233,7 +233,7 @@ unwind_frame_discard_internal (tag, ignore) { UNWIND_ELT *elt; - while (elt = unwind_protect_list) + while ((elt = unwind_protect_list)) { unwind_protect_list = unwind_protect_list->head.next; if (elt->head.cleanup == 0 && (STREQ (elt->arg.v, tag))) @@ -262,7 +262,7 @@ unwind_frame_run_internal (tag, ignore) { UNWIND_ELT *elt; - while (elt = unwind_protect_list) + while ((elt = unwind_protect_list)) { unwind_protect_list = elt->head.next; diff --git a/variables.c b/variables.c index 76501cf..488e4cf 100644 --- a/variables.c +++ b/variables.c @@ -149,8 +149,10 @@ static int export_env_size; #if defined (READLINE) static int winsize_assignment; /* currently assigning to LINES or COLUMNS */ +#if defined (STRICT_POSIX) static int winsize_assigned; /* assigned to LINES or COLUMNS */ #endif +#endif /* Non-zero means that we have to remake EXPORT_ENV. */ int array_needs_making = 1; @@ -172,9 +174,10 @@ static void uidset __P((void)); static void make_vers_array __P((void)); #endif -static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t)); #if defined (ARRAY_VARS) static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t)); +#else +static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t)); #endif static SHELL_VAR *get_self __P((SHELL_VAR *)); @@ -293,7 +296,7 @@ initialize_shell_variables (env, privmode) create_variable_tables (); - for (string_index = 0; string = env[string_index++]; ) + for (string_index = 0; (string = env[string_index++]); ) { char_index = 0; name = string; @@ -339,7 +342,7 @@ initialize_shell_variables (env, privmode) if (absolute_program (tname) == 0 && (posixly_correct == 0 || legal_identifier (tname))) parse_and_execute (temp_string, tname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD); - if (temp_var = find_function (tname)) + if ((temp_var = find_function (tname))) { VSETATTR (temp_var, (att_exported|att_imported)); array_needs_making = 1; @@ -426,7 +429,11 @@ initialize_shell_variables (env, privmode) #endif set_if_not ("PS2", secondary_prompt); } - set_if_not ("PS4", "+ "); + + if (current_user.euid == 0) + bind_variable ("PS4", "+ ", 0); + else + set_if_not ("PS4", "+ "); /* Don't allow IFS to be imported from the environment. */ temp_var = bind_variable ("IFS", " \t\n", 0); @@ -1054,21 +1061,21 @@ print_var_function (var) } \ while (0) +#if defined (ARRAY_VARS) static SHELL_VAR * -null_assign (self, value, unused) +null_array_assign (self, value, ind) SHELL_VAR *self; char *value; - arrayind_t unused; + arrayind_t ind; { return (self); } - -#if defined (ARRAY_VARS) +#else static SHELL_VAR * -null_array_assign (self, value, ind) +null_assign (self, value, unused) SHELL_VAR *self; char *value; - arrayind_t ind; + arrayind_t unused; { return (self); } @@ -1160,16 +1167,22 @@ static unsigned long rseed = 1; static int last_random_value; static int seeded_subshell = 0; -/* A linear congruential random number generator based on the example - one in the ANSI C standard. This one isn't very good, but a more - complicated one is overkill. */ +/* Use the random number genrator provided by the standard C library, + else use a linear congruential random number generator based on the + ANSI C standard. This one isn't very good (the values are alternately + odd and even, for example), but a more complicated one is overkill. */ /* Returns a pseudo-random number between 0 and 32767. */ static int brand () { +#if defined(HAVE_RANDOM) + rseed = (unsigned int) (labs(random()) & 32767); + return rseed; +#else rseed = rseed * 1103515245 + 12345; return ((unsigned int)((rseed >> 16) & 32767)); /* was % 32768 */ +#endif } /* Set the random number generator seed to SEED. */ @@ -1177,8 +1190,12 @@ static void sbrand (seed) unsigned long seed; { +#if defined(HAVE_SRANDOM) + srandom(seed); +#else rseed = seed; last_random_value = 0; +#endif } static SHELL_VAR * @@ -1523,7 +1540,7 @@ var_lookup (name, vcontext) v = (SHELL_VAR *)NULL; for (vc = vcontext; vc; vc = vc->down) - if (v = hash_lookup (name, vc->table)) + if ((v = hash_lookup (name, vc->table))) break; return v; @@ -1662,6 +1679,7 @@ make_local_variable (name) int was_tmpvar; char *tmp_value; + tmp_value = NULL; /* local foo; local foo; is a no-op. */ old_var = find_variable (name); if (old_var && local_p (old_var) && old_var->context == variable_context) @@ -1829,6 +1847,7 @@ make_variable_value (var, value, flags) evaluation done. */ if (integer_p (var)) { + lval = 0; if (flags & ASS_APPEND) { oval = value_cell (var); @@ -2394,7 +2413,7 @@ makunbound (name, vc) char *t; for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down) - if (elt = hash_remove (name, v->table, 0)) + if ((elt = hash_remove (name, v->table, 0))) break; if (elt == 0) @@ -3016,6 +3035,10 @@ merge_temporary_env () /* */ /* **************************************************************** */ +/* Returns the string NAME=VALUE if !FUNCTIONP or if VALUE == NULL (in + which case it is treated as empty). Otherwise, decorate NAME with + FUNCDEF_PREFIX and FUNCDEF_SUFFIX, and return a string of the form + FUNCDEF_PREFIX NAME FUNCDEF_SUFFIX = VALUE (without spaces). */ static inline char * mk_env_string (name, value, isfunc) const char *name, *value; @@ -3101,7 +3124,7 @@ make_env_array_from_var_list (vars) #define USE_EXPORTSTR (value == var->exportstr) - for (i = 0, list_index = 0; var = vars[i]; i++) + for (i = 0, list_index = 0; (var = vars[i]); i++) { #if defined (__CYGWIN__) /* We don't use the exportstr stuff on Cygwin at all. */ @@ -3515,7 +3538,7 @@ pop_var_context () return; } - if (ret = vcxt->down) + if ((ret = vcxt->down)) { ret->up = (VAR_CONTEXT *)NULL; shell_variables = ret; @@ -4094,7 +4117,7 @@ sv_history_control (name) return; tptr = 0; - while (val = extract_colon_unit (temp, &tptr)) + while ((val = extract_colon_unit (temp, &tptr))) { if (STREQ (val, "ignorespace")) history_control |= HC_IGNSPACE; diff --git a/y.tab.c b/y.tab.c index f8db50d..c821124 100644 --- a/y.tab.c +++ b/y.tab.c @@ -3832,6 +3832,8 @@ reset_parser () FREE (word_desc_to_read); word_desc_to_read = (WORD_DESC *)NULL; + eol_ungetc_lookahead = 0; + last_read_token = '\n'; token_to_read = '\n'; }