From: Chet Ramey Date: Wed, 7 Dec 2011 14:08:44 +0000 (-0500) Subject: commit bash-20070530 snapshot X-Git-Tag: bash-4.0-alpha~51 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b1a26c0178f1857ef4e51d0c4fca06b0f0a1db22;p=thirdparty%2Fbash.git commit bash-20070530 snapshot --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 61aafbca4..b4e572686 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -14699,3 +14699,29 @@ error.c - in get_name_for_error, use dollar_vars[0] if the name returned from looking in $BASH_SOURCE[0] is the empty string as well as if it's null + + 5/31 + ---- +arrayfunc.c + - change array_value_internal to set *RTYPE to 1 if the reference is + array[*] and 2 if the reference is array[@] + +subst.c + - in parameter_brace_expand_word, set the flags returned by the word + desc to include W_HASQUOTEDNULL if array_value returns QUOTED_NULL + for an array reference like x[*] and the word is quoted. Fixes bug + reported by Christophe Martin + + 6/1 + --- +jobs.c + - several changes to preserve errno if tcgetpgrp/tcgetattr/tcsetattr + fail, for subsequent error messages + - change initialize_job_control to turn off job control if the terminal + pgrp == -1 or is not equal to shell_pgrp (with an error message) + - in initialize_job_control, if the shell has been forced interactive + with -i, make sure stderr is hooked to a tty before using it as + the controlling terminal. If it's not, try to open /dev/tty and + assign it to shell_tty. Fixes problems reported by Derek Fawcus + + diff --git a/CWRU/CWRU.chlog~ b/CWRU/CWRU.chlog~ index 09f9fbd39..07b3b8636 100644 --- a/CWRU/CWRU.chlog~ +++ b/CWRU/CWRU.chlog~ @@ -14694,3 +14694,28 @@ variables.c,builtins/{declare,setattr,type}.def builtins/help.def - fix bug in `help' two-column printing to avoid referencing shell_builtins[num_shell_builtins] + +error.c + - in get_name_for_error, use dollar_vars[0] if the name returned from + looking in $BASH_SOURCE[0] is the empty string as well as if it's + null + + 5/31 + ---- +arrayfunc.c + - change array_value_internal to set *RTYPE to 1 if the reference is + array[*] and 2 if the reference is array[@] + +subst.c + - in parameter_brace_expand_word, set the flags returned by the word + desc to include W_HASQUOTEDNULL if array_value returns QUOTED_NULL + for an array reference like x[*] and the word is quoted. Fixes bug + reported by Christophe Martin + + 6/1 + --- +jobs.c + - several changes to preserve errno if tcgetpgrp/tcgetattr/tcsetattr + fail, for subsequent error messages + - change initialize_job_control to turn off job control if the terminal + pgrp == -1 or is not equal to shell_pgrp (with an error message) diff --git a/MANIFEST b/MANIFEST index 732527dd2..e788f4ff9 100644 --- a/MANIFEST +++ b/MANIFEST @@ -751,6 +751,7 @@ tests/exec4.sub f tests/exec5.sub f tests/exec6.sub f tests/exec7.sub f +tests/exec8.sub f tests/exp.tests f tests/exp.right f tests/exp1.sub f diff --git a/arrayfunc.c b/arrayfunc.c index 36727a3ce..98208bafe 100644 --- a/arrayfunc.c +++ b/arrayfunc.c @@ -693,8 +693,8 @@ array_variable_part (s, subp, lenp) /* Return a string containing the elements in the array and subscript described by S. If the subscript is * or @, obeys quoting rules akin to the expansion of $* and $@ including double quoting. If RTYPE - is non-null it gets 1 if the array reference is name[@] or name[*] - and 0 otherwise. */ + is non-null it gets 1 if the array reference is name[*], 2 if the + reference is name[@], and 0 otherwise. */ static char * array_value_internal (s, quoted, allow_all, rtype) char *s; @@ -722,7 +722,7 @@ array_value_internal (s, quoted, allow_all, rtype) if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']') { if (rtype) - *rtype = 1; + *rtype = (t[0] == '*') ? 1 : 2; if (allow_all == 0) { err_badarraysub (s); diff --git a/arrayfunc.c~ b/arrayfunc.c~ index 7a6904d99..36727a3ce 100644 --- a/arrayfunc.c~ +++ b/arrayfunc.c~ @@ -618,6 +618,8 @@ array_expand_index (s, len) if (expok == 0) { last_command_exit_value = EXECUTION_FAILURE; + + top_level_cleanup (); jump_to_top_level (DISCARD); } return val; diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c index 3923b8a06..8ebed4bad 100644 --- a/builtins/mkbuiltins.c +++ b/builtins/mkbuiltins.c @@ -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-2006 Free Software Foundation, Inc. +/* Copyright (C) 1987-2007 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -1080,7 +1080,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-2002 Free Software Foundation, Inc.", + "/* Copyright (C) 1987-2007 Free Software Foundation, Inc.", "", " This file is part of GNU Bash, the Bourne Again SHell.", "", diff --git a/builtins/mkbuiltins.c~ b/builtins/mkbuiltins.c~ index 8c737f8cc..3923b8a06 100644 --- a/builtins/mkbuiltins.c~ +++ b/builtins/mkbuiltins.c~ @@ -1224,7 +1224,7 @@ write_builtins (defs, structfile, externfile) document_name (builtin)); fprintf - (structfile, "N_( \"%s\"), (char *)NULL },\n", + (structfile, " N_(\"%s\"), (char *)NULL },\n", builtin->shortdoc ? builtin->shortdoc : builtin->name); } diff --git a/builtins/reserved.def b/builtins/reserved.def index 8b598b046..3a14ad2e5 100644 --- a/builtins/reserved.def +++ b/builtins/reserved.def @@ -148,7 +148,7 @@ $DOCNAME variable_help $SHORT_DOC variables - Names and meanings of some shell variables BASH_VERSION Version information for this Bash. CDPATH A colon-separated list of directories to search - for directries given as arguments to `cd'. + for directories given as arguments to `cd'. GLOBIGNORE A colon-separated list of patterns describing filenames to be ignored by pathname expansion. #if defined (HISTORY) diff --git a/doc/FAQ b/doc/FAQ index b2cf39175..4cebba094 100644 --- a/doc/FAQ +++ b/doc/FAQ @@ -1774,7 +1774,12 @@ this: echo .!(.|) * A solution that works without extended globbing is given in the Unix Shell -FAQ, posted periodically to comp.unix.shell. +FAQ, posted periodically to comp.unix.shell. It's a variant of + + echo .[!.]* ..?* * + +(The ..?* catches files with names of three or more characters beginning +with `..') Section H: Where do I go from here? diff --git a/doc/FAQ~ b/doc/FAQ~ index dd3ea566a..b2cf39175 100644 --- a/doc/FAQ~ +++ b/doc/FAQ~ @@ -1,4 +1,4 @@ -This is the Bash FAQ, version 3.35, for Bash version 3.2. +This is the Bash FAQ, version 3.36, for Bash version 3.2. This document contains a set of frequently-asked questions concerning Bash, the GNU Bourne-Again Shell. Bash is a freely-available command @@ -79,6 +79,8 @@ E11) If I resize my xterm while another program is running, why doesn't bash notice the change? E12) Why don't negative offsets in substring expansion work like I expect? E13) Why does filename completion misbehave if a colon appears in the filename? +E14) Why does quoting the pattern argument to the regular expression matching + conditional operator (=~) cause matching to stop working? Section F: Things to watch out for on certain Unix versions @@ -1427,6 +1429,34 @@ COMP_WORDBREAKS=${COMP_WORDBREAKS//:} You can also quote the colon with a backslash to achieve the same result temporarily. +E14) Why does quoting the pattern argument to the regular expression matching + conditional operator (=~) cause regexp matching to stop working? + +In versions of bash prior to bash-3.2, the effect of quoting the regular +expression argument to the [[ command's =~ operator was not specified. +The practical effect was that double-quoting the pattern argument required +backslashes to quote special pattern characters, which interfered with the +backslash processing performed by double-quoted word expansion and was +inconsistent with how the == shell pattern matching operator treated +quoted characters. + +In bash-3.2, the shell was changed to internally quote characters in single- +and double-quoted string arguments to the =~ operator, which suppresses the +special meaning of the characters special to regular expression processing +(`.', `[', `\', `(', `), `*', `+', `?', `{', `|', `^', and `$') and forces +them to be matched literally. This is consistent with how the `==' pattern +matching operator treats quoted portions of its pattern argument. + +Since the treatment of quoted string arguments was changed, several issues +have arisen, chief among them the problem of white space in pattern arguments +and the differing treatment of quoted strings between bash-3.1 and bash-3.2. +Both problems may be solved by using a shell variable to hold the pattern. +Since word splitting is not performed when expanding shell variables in all +operands of the [[ command, this allows users to quote patterns as they wish +when assigning the variable, then expand the values to a single string that +may contain whitespace. The first problem may be solved by using backslashes +or any other quoting mechanism to escape the white space in the patterns. + Section F: Things to watch out for on certain Unix versions F1) Why can't I use command line editing in my `cmdtool'? diff --git a/doc/bash.1 b/doc/bash.1 index 5a3d2ee58..689de6a1e 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -577,7 +577,7 @@ and have equal precedence, followed by .B ; and -.BR &, +.BR & , which have equal precedence. .PP A sequence of one or more newlines may appear in a \fIlist\fP instead diff --git a/jobs.c b/jobs.c index 079b54fb5..d94cc5fa3 100644 --- a/jobs.c +++ b/jobs.c @@ -1967,7 +1967,7 @@ get_tty_state () /* Only print an error message if we're really interactive at this time. */ if (interactive) - sys_error ("[%ld: %d] tcgetattr", (long)getpid (), shell_level); + sys_error ("[%ld: %d (%d)] tcgetattr", (long)getpid (), shell_level, tty); #endif return -1; } @@ -2006,7 +2006,7 @@ set_tty_state () /* Only print an error message if we're really interactive at this time. */ if (interactive) - sys_error ("[%ld: %d] tcsetattr", (long)getpid (), shell_level); + sys_error ("[%ld: %d (%d)] tcsetattr", (long)getpid (), shell_level, tty); return -1; } #endif /* TERMIOS_TTY_DRIVER */ @@ -3477,6 +3477,10 @@ int initialize_job_control (force) int force; { + pid_t t; + int t_errno; + + t_errno = -1; shell_pgrp = getpgid (0); if (shell_pgrp == -1) @@ -3494,10 +3498,21 @@ initialize_job_control (force) } else { + shell_tty = -1; + + /* If forced_interactive is set, we skip the normal check that stderr + is attached to a tty, so we need to check here. If it's not, we + need to see whether we have a controlling tty by opening /dev/tty, + since trying to use job control tty pgrp manipulations on a non-tty + is going to fail. */ + if (forced_interactive && isatty (fileno (stderr)) == 0) + shell_tty = open ("/dev/tty", O_RDWR|O_NONBLOCK); + /* Get our controlling terminal. If job_control is set, or interactive is set, then this is an interactive shell no matter where fd 2 is directed. */ - shell_tty = dup (fileno (stderr)); /* fd 2 */ + if (shell_tty == -1) + shell_tty = dup (fileno (stderr)); /* fd 2 */ shell_tty = move_to_high_fd (shell_tty, 1, -1); @@ -3524,6 +3539,9 @@ initialize_job_control (force) break; } + if (terminal_pgrp == -1) + t_errno = errno; + /* Make sure that we are using the new line discipline. */ if (set_new_line_discipline (shell_tty) < 0) { @@ -3554,11 +3572,20 @@ initialize_job_control (force) { if (give_terminal_to (shell_pgrp, 0) < 0) { + t_errno = errno; setpgid (0, original_pgrp); shell_pgrp = original_pgrp; job_control = 0; } } + + if (job_control && ((t = tcgetpgrp (shell_tty)) == -1 || t != shell_pgrp)) + { + if (t_errno != -1) + errno = t_errno; + sys_error (_("cannot set terminal process group (%d)"), t); + job_control = 0; + } } if (job_control == 0) internal_error (_("no job control in this shell")); @@ -3708,7 +3735,7 @@ give_terminal_to (pgrp, force) int force; { sigset_t set, oset; - int r; + int r, e; r = 0; if (job_control || force) @@ -3729,12 +3756,15 @@ give_terminal_to (pgrp, force) shell_tty, (long)getpid(), (long)pgrp); #endif r = -1; + e = errno; } else terminal_pgrp = pgrp; sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL); } + if (r == -1) + errno = e; return r; } diff --git a/jobs.c~ b/jobs.c~ index 0ff2d591e..a5ac42211 100644 --- a/jobs.c~ +++ b/jobs.c~ @@ -137,6 +137,8 @@ extern int errno; /* The number of additional slots to allocate when we run out. */ #define JOB_SLOTS 8 +#define CTTYFD 2 + typedef int sh_job_map_func_t __P((JOB *, int, int, int)); /* Variables used here but defined in other files. */ @@ -1967,7 +1969,7 @@ get_tty_state () /* Only print an error message if we're really interactive at this time. */ if (interactive) - sys_error ("[%ld: %d] tcgetattr", (long)getpid (), shell_level); + sys_error ("[%ld: %d (%d)] tcgetattr", (long)getpid (), shell_level, tty); #endif return -1; } @@ -2006,7 +2008,7 @@ set_tty_state () /* Only print an error message if we're really interactive at this time. */ if (interactive) - sys_error ("[%ld: %d] tcsetattr", (long)getpid (), shell_level); + sys_error ("[%ld: %d (%d)] tcsetattr", (long)getpid (), shell_level, tty); return -1; } #endif /* TERMIOS_TTY_DRIVER */ @@ -3477,6 +3479,10 @@ int initialize_job_control (force) int force; { + pid_t t; + int t_errno; + + t_errno = -1; shell_pgrp = getpgid (0); if (shell_pgrp == -1) @@ -3494,10 +3500,15 @@ initialize_job_control (force) } else { + shell_tty = -1; + if (forced_interactive && isatty (fileno (stderr)) == 0) + shell_tty = open ("/dev/tty", O_RDWR|O_NONBLOCK); + /* Get our controlling terminal. If job_control is set, or interactive is set, then this is an interactive shell no matter where fd 2 is directed. */ - shell_tty = dup (fileno (stderr)); /* fd 2 */ + if (shell_tty == -1) + shell_tty = dup (fileno (stderr)); /* fd 2 */ shell_tty = move_to_high_fd (shell_tty, 1, -1); @@ -3524,6 +3535,9 @@ initialize_job_control (force) break; } + if (terminal_pgrp == -1) + t_errno = errno; + /* Make sure that we are using the new line discipline. */ if (set_new_line_discipline (shell_tty) < 0) { @@ -3554,12 +3568,20 @@ initialize_job_control (force) { if (give_terminal_to (shell_pgrp, 0) < 0) { + t_errno = errno; setpgid (0, original_pgrp); shell_pgrp = original_pgrp; job_control = 0; -internal_error ("cannot set terminal pgrp to %d: %s", shell_pgrp, strerror (errno)); } } + + if (job_control && ((t = tcgetpgrp (shell_tty)) == -1 || t != shell_pgrp)) + { + if (t_errno != -1) + errno = t_errno; + sys_error (_("cannot set terminal process group (%d)"), t); + job_control = 0; + } } if (job_control == 0) internal_error (_("no job control in this shell")); @@ -3709,7 +3731,7 @@ give_terminal_to (pgrp, force) int force; { sigset_t set, oset; - int r; + int r, e; r = 0; if (job_control || force) @@ -3730,12 +3752,15 @@ give_terminal_to (pgrp, force) shell_tty, (long)getpid(), (long)pgrp); #endif r = -1; + e = errno; } else terminal_pgrp = pgrp; sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL); } + if (r == -1) + errno = e; return r; } diff --git a/subst.c b/subst.c index 955eba641..a71229f27 100644 --- a/subst.c +++ b/subst.c @@ -4958,10 +4958,11 @@ parameter_brace_expand_word (name, var_is_special, quoted) char *temp, *tt; intmax_t arg_index; SHELL_VAR *var; - int atype; + int atype, rflags; ret = 0; temp = 0; + rflags = 0; /* Handle multiple digit arguments, as in ${11}. */ if (legal_number (name, &arg_index)) @@ -4994,6 +4995,8 @@ parameter_brace_expand_word (name, var_is_special, quoted) temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) ? quote_string (temp) : quote_escapes (temp); + else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) + rflags |= W_HASQUOTEDNULL; } #endif else if (var = find_variable (name)) @@ -5021,6 +5024,7 @@ parameter_brace_expand_word (name, var_is_special, quoted) { ret = alloc_word_desc (); ret->word = temp; + ret->flags |= rflags; } return ret; } diff --git a/subst.c~ b/subst.c~ index b18d56db7..b3250747f 100644 --- a/subst.c~ +++ b/subst.c~ @@ -211,7 +211,6 @@ static WORD_LIST *list_quote_escapes __P((WORD_LIST *)); static char *dequote_escapes __P((char *)); static char *make_quoted_char __P((int)); static WORD_LIST *quote_list __P((WORD_LIST *)); -/*static*/ char *remove_quoted_escapes __P((char *)); static char *remove_quoted_nulls __P((char *)); static int unquoted_substring __P((char *, char *)); @@ -3201,7 +3200,7 @@ dequote_list (list) /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed string. */ -/*static*/ char * +char * remove_quoted_escapes (string) char *string; { @@ -4959,10 +4958,11 @@ parameter_brace_expand_word (name, var_is_special, quoted) char *temp, *tt; intmax_t arg_index; SHELL_VAR *var; - int atype; + int atype, rflags; ret = 0; temp = 0; + rflags = 0; /* Handle multiple digit arguments, as in ${11}. */ if (legal_number (name, &arg_index)) @@ -4995,6 +4995,8 @@ parameter_brace_expand_word (name, var_is_special, quoted) temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) ? quote_string (temp) : quote_escapes (temp); + else if (atype == 1 && temp && *temp == 0 && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) + rflags |= W_HASQUOTEDNULL; } #endif else if (var = find_variable (name)) @@ -5022,6 +5024,7 @@ parameter_brace_expand_word (name, var_is_special, quoted) { ret = alloc_word_desc (); ret->word = temp; + ret->flags |= rflags; } return ret; } diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index 72ec06a2c..3efcf32d6 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -1,4 +1,4 @@ -BUILD_DIR=/usr/local/build/bash/bash-current +BUILD_DIR=/usr/local/build/chet/bash/bash-current THIS_SH=$BUILD_DIR/bash PATH=$PATH:$BUILD_DIR