diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 227bb13b..bf119c4c 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -12661,3 +12661,91 @@ lib/glob/glob.c - glob_filename: assign the return value of realloc (results, ...) to a temp pointer, so if realloc returns NULL, we make sure we free results. Report from Kirill Timofeev + + 12/12 + ----- +lib/sh/shquote.c + - sh_backslash_quote: if FLAGS&2, backslash-quote other single-byte + characters that are in the current locale's character class + +builtins/printf.def + - printf_builtin: when processing the `%q' format, make sure to + backslash quote all characters by making sure that FLAGS + passed to sh_backslash_quote includes 2. Fixes issue for certain + iso-8859-1 locales where character 160 (octal 240, hex 0xa0) is a + non-breaking space. Report from Stephane Chazelas + + +lib/sh/eaccess.c + - sh_stat: if DEV_FD_STAT_BROKEN is defined, take /dev/fd/N and turn + it into a stat on file descriptor N, as if /dev/fd were not + available. This is the case on some old versions of SunOS. Report + and patch from Dmitry Goncharov + +config.h.in + - DEV_FD_STAT_BROKEN: add define + +configure.ac + - --enable-dev-fd-stat-broken: new command-line option, defines + DEV_FD_STAT_BROKEN if supplied at configure time + +doc/bashref.texi + - --enable-dev-fd-stat-broken: document new command-line option for + configure + +arrayfunc.c + - assoc_expand_once: new variable, declared here just because + +arrayfunc.h + - assoc_expand_once: extern declaration + - AV_NOEXPAND: new flag value for the array_value family of functions: + means to not run associative array subscripts through word expansion + +builtins/set.def + - unset_builtin: call unbind_array_element with assoc_expand_once as + third arg, controls whether we expand associative array subscripts + (if 1, we suppress the usual expansion). With accompanying shopt, + provides backwards compatible option to solve problem with quotes + and other characters in associative array subscripts pointed out + most recently by Mingye Wang (Arthur2e5) + +builtins/shopt.def + - assoc_expand_once: new option, controls value of internal variable + with the same name. Currently undocumented because I'm not completely + sold on the name + +expr.c + - evalexp: now takes a second argument, flags. Changed all callers in + multiple other files (builtins/let.def,execute_cmd.c,arrayfunc.c, + subst.c,test.c,variables.c) + +externs.h + - EXP_EXPANDED, new flag for second argument to evalexp + +builtins/let.def + - let_builtin: add EXP_EXPANDED to flags passed to evalexp + +execute_cmd.c + - execute_arith_command: add EXP_EXPANDED to flags passed to evalexp, + since the command string is run through expand_words_no_vars before + being evaluated + +expr.c + - set expression-global variable already_expanded if flags arg to + evalexp contains EXP_EXPANDED + - if assoc_expand_once option set and already_expanded flag set, pass + 1 in flags to array_variable_part to skip over quotes and expansions + in the subscript + - if those two variables set, pass AV_NOEXPAND as flag to + get_array_value to prevent word expansions on the subscript + +arrayfunc.c + - if flags passed to unbind_array_element includes 1, pass flag on to + skipsubscript so we don't expect matched quotes or process + expansions in the subscript + - if flags to array_value_internal include AV_NOEXPAND, pass 1 as flag + to array_variable_part to pass along to skipsubscript + - if flags to array_value_internal include AV_NOEXPAND, don't call + expand_assignment_string_to_string; just use the unexpanded subscript + to produce the key [THIS IS A WORK IN PROGRESS] + diff --git a/MANIFEST b/MANIFEST index dc203c6e..d033b3fa 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1282,6 +1282,7 @@ tests/shopt.right f tests/strip.tests f tests/strip.right f tests/test.tests f +tests/test1.sub f tests/test.right f tests/tilde.tests f tests/tilde.right f diff --git a/RUN-ONE-TEST b/RUN-ONE-TEST deleted file mode 100755 index d29259a9..00000000 --- a/RUN-ONE-TEST +++ /dev/null @@ -1,10 +0,0 @@ -BUILD_DIR=/usr/local/build/chet/bash/bash-current -THIS_SH=$BUILD_DIR/bash -PATH=$PATH:$BUILD_DIR - -export THIS_SH PATH - -export BASH_TSTOUT=/tmp/xx -rm -f ${BASH_TSTOUT} - -/bin/sh "$@" diff --git a/arrayfunc.c b/arrayfunc.c index 786b8ec6..c31afc50 100644 --- a/arrayfunc.c +++ b/arrayfunc.c @@ -43,6 +43,10 @@ extern char *this_command_name; extern int last_command_exit_value; extern int array_needs_making; +/* This variable means to not expand associative array subscripts more than + once, when performing variable expansion. */ +int assoc_expand_once = 0; + static SHELL_VAR *bind_array_var_internal __P((SHELL_VAR *, arrayind_t, char *, char *, int)); static SHELL_VAR *assign_array_element_internal __P((SHELL_VAR *, char *, char *, char *, int, char *, int)); @@ -759,6 +763,7 @@ quote_array_assignment_chars (list) /* This function is called with SUB pointing to just after the beginning `[' of an array subscript and removes the array element to which SUB expands from array VAR. A subscript of `*' or `@' unsets the array. */ +/* If FLAGS&1 we don't expand the subscript; we just use it as-is. */ int unbind_array_element (var, sub, flags) SHELL_VAR *var; @@ -770,7 +775,7 @@ unbind_array_element (var, sub, flags) char *akey; ARRAY_ELEMENT *ae; - len = skipsubscript (sub, 0, (var && assoc_p(var))); + len = skipsubscript (sub, 0, (flags&1) || (var && assoc_p(var))); if (sub[len] != ']' || len == 0) { builtin_error ("%s[%s: %s", var->name, sub, _(bash_badsub_errmsg)); @@ -928,7 +933,7 @@ array_expand_index (var, s, len) t = expand_arith_string (exp, Q_DOUBLE_QUOTES|Q_ARITH|Q_ARRAYSUB); /* XXX - Q_ARRAYSUB for future use */ savecmd = this_command_name; this_command_name = (char *)NULL; - val = evalexp (t, &expok); + val = evalexp (t, 0, &expok); this_command_name = savecmd; free (t); free (exp); @@ -1046,7 +1051,7 @@ array_value_internal (s, quoted, flags, rtype, indp) WORD_LIST *l; SHELL_VAR *var; - var = array_variable_part (s, 0, &t, &len); + var = array_variable_part (s, (flags&AV_NOEXPAND) ? 1 : 0, &t, &len); /* XXX */ /* Expand the index, even if the variable doesn't exist, in case side effects are needed, like ${w[i++]} where w is unset. */ @@ -1126,7 +1131,10 @@ array_value_internal (s, quoted, flags, rtype, indp) else if (assoc_p (var)) { t[len - 1] = '\0'; - akey = expand_assignment_string_to_string (t, 0); /* [ */ + if ((flags & AV_NOEXPAND) == 0) + akey = expand_assignment_string_to_string (t, 0); /* [ */ + else + akey = savestring (t); t[len - 1] = ']'; if (akey == 0 || *akey == 0) { diff --git a/arrayfunc.h b/arrayfunc.h index 9b51ca2b..07f0302c 100644 --- a/arrayfunc.h +++ b/arrayfunc.h @@ -25,12 +25,17 @@ #if defined (ARRAY_VARS) +/* This variable means to not expand associative array subscripts more than + once, when performing variable expansion. */ +extern int assoc_expand_once; + /* Flags for array_value_internal and callers array_value/get_array_value */ #define AV_ALLOWALL 0x001 #define AV_QUOTED 0x002 #define AV_USEIND 0x004 #define AV_USEVAL 0x008 /* XXX - should move this */ #define AV_ASSIGNRHS 0x010 /* no splitting, special case ${a[@]} */ +#define AV_NOEXPAND 0x020 /* don't run assoc subscripts through word expansion */ extern SHELL_VAR *convert_var_to_array __P((SHELL_VAR *)); extern SHELL_VAR *convert_var_to_assoc __P((SHELL_VAR *)); diff --git a/builtins/let.def b/builtins/let.def index 23e684fd..d090a45b 100644 --- a/builtins/let.def +++ b/builtins/let.def @@ -100,7 +100,7 @@ let_builtin (list) for (; list; list = list->next) { - ret = evalexp (list->word->word, &expok); + ret = evalexp (list->word->word, EXP_EXPANDED, &expok); if (expok == 0) return (EXECUTION_FAILURE); } @@ -124,7 +124,7 @@ exp_builtin (list) } exp = string_list (list); - ret = evalexp (exp, &expok); + ret = evalexp (exp, EXP_EXPANDED, &expok); (void)free (exp); return (((ret == 0) || (expok == 0)) ? EXECUTION_FAILURE : EXECUTION_SUCCESS); } diff --git a/builtins/printf.def b/builtins/printf.def index 03687814..e6b82c02 100644 --- a/builtins/printf.def +++ b/builtins/printf.def @@ -577,7 +577,7 @@ printf_builtin (list) else if (ansic_shouldquote (p)) xp = ansic_quote (p, 0, (int *)0); else - xp = sh_backslash_quote (p, 0, 1); + xp = sh_backslash_quote (p, 0, 3); if (xp) { /* Use printstr to get fieldwidth and precision right. */ diff --git a/builtins/set.def b/builtins/set.def index 5ede5b94..a6a70aa2 100644 --- a/builtins/set.def +++ b/builtins/set.def @@ -916,11 +916,7 @@ unset_builtin (list) if (var && unset_array) { /* Let unbind_array_element decide what to do with non-array vars */ -#if 0 - tem = unbind_array_element (var, t, 1); /* XXX new third arg */ -#else - tem = unbind_array_element (var, t, 0); /* XXX new third arg */ -#endif + tem = unbind_array_element (var, t, assoc_expand_once); /* XXX new third arg */ if (tem == -2 && array_p (var) == 0 && assoc_p (var) == 0) { builtin_error (_("%s: not an array variable"), var->name); @@ -943,11 +939,7 @@ unset_builtin (list) { tname = savestring (nameref_cell (var)); if (var = array_variable_part (tname, 0, &t, (int *)0)) -#if 0 - tem = unbind_array_element (var, t, 1); /* XXX new third arg */ -#else - tem = unbind_array_element (var, t, 0); /* XXX new third arg */ -#endif + tem = unbind_array_element (var, t, assoc_expand_once); /* XXX new third arg */ free (tname); } else diff --git a/builtins/shopt.def b/builtins/shopt.def index 0d165fa8..615c7cc6 100644 --- a/builtins/shopt.def +++ b/builtins/shopt.def @@ -118,6 +118,10 @@ extern char *shell_name; extern int debugging_mode; #endif +#if defined (ARRAY_VARS) +extern int assoc_expand_once; +#endif + static void shopt_error __P((char *)); static int set_shellopts_after_change __P((char *, int)); @@ -153,6 +157,9 @@ static struct { shopt_set_func_t *set_func; } shopt_vars[] = { { "autocd", &autocd, (shopt_set_func_t *)NULL }, +#if defined (ARRAY_VARS) + { "assoc_expand_once", &assoc_expand_once, (shopt_set_func_t *)NULL }, +#endif { "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL }, { "cdspell", &cdspelling, (shopt_set_func_t *)NULL }, { "checkhash", &check_hashed_filenames, (shopt_set_func_t *)NULL }, diff --git a/config.h.in b/config.h.in index 3de3abd7..b5c35c38 100644 --- a/config.h.in +++ b/config.h.in @@ -1132,6 +1132,8 @@ #undef GETCWD_BROKEN +#undef DEV_FD_STAT_BROKEN + /* Additional defines for configuring lib/intl, maintained by autoscan/autoheader */ /* Define if you have the header file. */ diff --git a/configure b/configure index 40438402..cd659978 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac for Bash 4.4, version 4.086. +# From configure.ac for Bash 4.4, version 4.087. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for bash 4.4-maint. # @@ -802,6 +802,7 @@ enable_cond_command enable_cond_regexp enable_coprocesses enable_debugger +enable_dev_fd_stat_broken enable_direxpand_default enable_directory_stack enable_disabled_builtins @@ -1486,6 +1487,9 @@ Optional Features: --enable-coprocesses enable coprocess support and the coproc reserved word --enable-debugger enable support for bash debugger + --enable-dev-fd-stat-broken + enable this option if stat on /dev/fd/N and fstat on + file descriptor N don't return the same results --enable-direxpand-default enable the direxpand shell option by default --enable-directory-stack @@ -2979,6 +2983,7 @@ opt_extglob_default=no opt_dircomplete_expand_default=no opt_globascii_default=no opt_function_import=yes +opt_dev_fd_stat_broken=no opt_static_link=no opt_profiling=no @@ -3062,6 +3067,11 @@ if test "${enable_debugger+set}" = set; then : enableval=$enable_debugger; opt_debugger=$enableval fi +# Check whether --enable-dev-fd-stat-broken was given. +if test "${enable_dev_fd_stat_broken+set}" = set; then : + enableval=$enable_dev_fd_stat_broken; opt_dev_fd_stat_broken=$enableval +fi + # Check whether --enable-direxpand-default was given. if test "${enable_direxpand_default+set}" = set; then : enableval=$enable_direxpand_default; opt_dircomplete_expand_default=$enableval @@ -3327,6 +3337,10 @@ fi if test $opt_function_import = yes; then $as_echo "#define FUNCTION_IMPORT 1" >>confdefs.h +fi +if test $opt_dev_fd_stat_broken = yes; then +$as_echo "#define DEV_FD_STAT_BROKEN 1" >>confdefs.h + fi if test $opt_memscramble = yes; then diff --git a/configure.ac b/configure.ac index 4a28b56f..5142da25 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script. # You should have received a copy of the GNU General Public License # along with this program. If not, see . -AC_REVISION([for Bash 4.4, version 4.086])dnl +AC_REVISION([for Bash 4.4, version 4.087])dnl define(bashvers, 4.4) define(relstatus, maint) @@ -179,6 +179,7 @@ opt_extglob_default=no opt_dircomplete_expand_default=no opt_globascii_default=no opt_function_import=yes +opt_dev_fd_stat_broken=no dnl options that affect how bash is compiled and linked opt_static_link=no @@ -214,6 +215,7 @@ AC_ARG_ENABLE(cond-command, AC_HELP_STRING([--enable-cond-command], [enable the AC_ARG_ENABLE(cond-regexp, AC_HELP_STRING([--enable-cond-regexp], [enable extended regular expression matching in conditional commands]), opt_cond_regexp=$enableval) AC_ARG_ENABLE(coprocesses, AC_HELP_STRING([--enable-coprocesses], [enable coprocess support and the coproc reserved word]), opt_coproc=$enableval) AC_ARG_ENABLE(debugger, AC_HELP_STRING([--enable-debugger], [enable support for bash debugger]), opt_debugger=$enableval) +AC_ARG_ENABLE(dev-fd-stat-broken, AC_HELP_STRING([--enable-dev-fd-stat-broken], [enable this option if stat on /dev/fd/N and fstat on file descriptor N don't return the same results]), opt_dev_fd_stat_broken=$enableval) AC_ARG_ENABLE(direxpand-default, AC_HELP_STRING([--enable-direxpand-default], [enable the direxpand shell option by default]), opt_dircomplete_expand_default=$enableval) AC_ARG_ENABLE(directory-stack, AC_HELP_STRING([--enable-directory-stack], [enable builtins pushd/popd/dirs]), opt_dirstack=$enableval) AC_ARG_ENABLE(disabled-builtins, AC_HELP_STRING([--enable-disabled-builtins], [allow disabled builtins to still be invoked]), opt_disabled_builtins=$enableval) @@ -347,6 +349,9 @@ fi if test $opt_function_import = yes; then AC_DEFINE(FUNCTION_IMPORT) fi +if test $opt_dev_fd_stat_broken = yes; then +AC_DEFINE(DEV_FD_STAT_BROKEN) +fi if test $opt_memscramble = yes; then AC_DEFINE(MEMSCRAMBLE) diff --git a/doc/bashref.texi b/doc/bashref.texi index aefe3e4a..3656f59d 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -8346,6 +8346,12 @@ Include support for coprocesses and the @code{coproc} reserved word @item --enable-debugger Include support for the bash debugger (distributed separately). +@item --enable-dev-fd-stat-broken +If calling @code{stat} on /dev/fd/@var{N} returns different results than +calling @code{fstat} on file descriptor @var{N}, supply this option to +enable a workaround. +This has implications for conditional commands that test file attributes. + @item --enable-direxpand-default Cause the @code{direxpand} shell option (@pxref{The Shopt Builtin}) to be enabled by default when the shell starts. diff --git a/doc/version.texi b/doc/version.texi index 9231062e..fc58e42e 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -2,10 +2,10 @@ Copyright (C) 1988-2016 Free Software Foundation, Inc. @end ignore -@set LASTCHANGE Wed Nov 30 10:06:51 PST 2016 +@set LASTCHANGE Mon Dec 12 12:26:16 EST 2016 @set EDITION 4.4 @set VERSION 4.4 -@set UPDATED 30 November 2016 -@set UPDATED-MONTH November 2016 +@set UPDATED 12 December 2016 +@set UPDATED-MONTH December 2016 diff --git a/execute_cmd.c b/execute_cmd.c index 27ef9668..41ac4209 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -2911,7 +2911,7 @@ eval_arith_for_expr (l, okp) skip the command. */ #if defined (DEBUGGER) if (debugging_mode == 0 || r == EXECUTION_SUCCESS) - expresult = evalexp (new->word->word, okp); + expresult = evalexp (new->word->word, 0, okp); else { expresult = 0; @@ -2919,7 +2919,7 @@ eval_arith_for_expr (l, okp) *okp = 1; } #else - expresult = evalexp (new->word->word, okp); + expresult = evalexp (new->word->word, 0, okp); #endif dispose_words (new); } @@ -3642,7 +3642,7 @@ execute_arith_command (arith_command) if (new) { exp = new->next ? string_list (new) : new->word->word; - expresult = evalexp (exp, &expok); + expresult = evalexp (exp, EXP_EXPANDED, &expok); line_number = save_line_number; if (exp != new->word->word) free (exp); diff --git a/expr.c b/expr.c index 38a355a1..8fc9b359 100644 --- a/expr.c +++ b/expr.c @@ -171,6 +171,9 @@ static intmax_t tokval; /* current token value */ static int noeval; /* set to 1 if no assignment to be done */ static procenv_t evalbuf; +/* set to 1 if the expression has already been run through word expansion */ +static int already_expanded; + static struct lvalue curlval = {0, 0, 0, -1}; static struct lvalue lastlval = {0, 0, 0, -1}; @@ -221,6 +224,7 @@ extern char *this_command_name; extern int unbound_vars_is_error, last_command_exit_value; #if defined (ARRAY_VARS) +extern int assoc_expand_once; extern const char * const bash_badsub_errmsg; #endif @@ -362,8 +366,9 @@ expr_bind_array_element (tok, ind, rhs) safe to let the loop terminate when expr_depth == 0, without freeing up any of the expr_depth[0] stuff. */ intmax_t -evalexp (expr, validp) +evalexp (expr, flags, validp) char *expr; + int flags; int *validp; { intmax_t val; @@ -372,6 +377,7 @@ evalexp (expr, validp) val = 0; noeval = 0; + already_expanded = (flags&EXP_EXPANDED); FASTCOPY (evalbuf, oevalbuf, sizeof (evalbuf)); @@ -1095,17 +1101,20 @@ expr_streval (tok, e, lvalue) intmax_t tval; #if defined (ARRAY_VARS) arrayind_t ind; + int tflag, aflag; #endif -/*itrace("expr_streval: %s: noeval = %d", tok, noeval);*/ +/*itrace("expr_streval: %s: noeval = %d expanded=%d", tok, noeval, already_expanded);*/ /* If we are suppressing evaluation, just short-circuit here instead of going through the rest of the evaluator. */ if (noeval) return (0); + tflag = assoc_expand_once && already_expanded; /* for a start */ /* [[[[[ */ #if defined (ARRAY_VARS) - v = (e == ']') ? array_variable_part (tok, 0, (char **)0, (int *)0) : find_variable (tok); + aflag = (tflag) ? AV_NOEXPAND : 0; + v = (e == ']') ? array_variable_part (tok, tflag, (char **)0, (int *)0) : find_variable (tok); #else v = find_variable (tok); #endif @@ -1113,7 +1122,7 @@ expr_streval (tok, e, lvalue) if ((v == 0 || invisible_p (v)) && unbound_vars_is_error) { #if defined (ARRAY_VARS) - value = (e == ']') ? array_variable_name (tok, 0, (char **)0, (int *)0) : tok; + value = (e == ']') ? array_variable_name (tok, tflag, (char **)0, (int *)0) : tok; #else value = tok; #endif @@ -1145,7 +1154,7 @@ expr_streval (tok, e, lvalue) references like array[@]. In this case, get_array_value is just like get_variable_value in that it does not return newly-allocated memory or quote the results. */ - value = (e == ']') ? get_array_value (tok, 0, (int *)NULL, &ind) : get_variable_value (v); + value = (e == ']') ? get_array_value (tok, aflag, (int *)NULL, &ind) : get_variable_value (v); #else value = get_variable_value (v); #endif @@ -1564,7 +1573,7 @@ main (argc, argv) for (i = 1; i < argc; i++) { - v = evalexp (argv[i], &expok); + v = evalexp (argv[i], 0, &expok); if (expok == 0) fprintf (stderr, _("%s: expression error\n"), argv[i]); else diff --git a/externs.h b/externs.h index 0ad223c6..925e946e 100644 --- a/externs.h +++ b/externs.h @@ -27,7 +27,9 @@ #include "stdc.h" /* Functions from expr.c. */ -extern intmax_t evalexp __P((char *, int *)); +#define EXP_EXPANDED 0x01 + +extern intmax_t evalexp __P((char *, int, int *)); /* Functions from print_cmd.c. */ #define FUNC_MULTILINE 0x01 diff --git a/lib/sh/eaccess.c b/lib/sh/eaccess.c index 8fd8a43e..3d8ae4e8 100644 --- a/lib/sh/eaccess.c +++ b/lib/sh/eaccess.c @@ -91,7 +91,9 @@ sh_stat (path, finfo) } if (path[0] == '/' && path[1] == 'd' && strncmp (path, "/dev/fd/", 8) == 0) { -#if !defined (HAVE_DEV_FD) + /* If stating /dev/fd/n doesn't produce the same results as fstat of + FD N, then define DEV_FD_STAT_BROKEN */ +#if !defined (HAVE_DEV_FD) || defined (DEV_FD_STAT_BROKEN) intmax_t fd; int r; diff --git a/lib/sh/shquote.c b/lib/sh/shquote.c index ecec5971..97e2bc53 100644 --- a/lib/sh/shquote.c +++ b/lib/sh/shquote.c @@ -228,7 +228,8 @@ sh_un_double_quote (string) going through the shell parser, which will protect the internal quoting characters. TABLE, if set, points to a map of the ascii code set with char needing to be backslash-quoted if table[char]==1. FLAGS, - if 1, causes tildes to be quoted as well. */ + if 1, causes tildes to be quoted as well. If FLAGS&2, backslash-quote + other shell blank characters. */ char * sh_backslash_quote (string, table, flags) @@ -273,6 +274,8 @@ sh_backslash_quote (string, table, flags) /* Tildes are special at the start of a word or after a `:' or `=' (technically unquoted, but it doesn't make a difference in practice) */ *r++ = '\\'; + else if ((flags&2) && shellblank((unsigned char)c)) + *r++ = '\\'; *r++ = c; } diff --git a/subst.c b/subst.c index 55dae72c..9ddbcc19 100644 --- a/subst.c +++ b/subst.c @@ -180,6 +180,13 @@ WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL; errors. Enabled when doing completion and prompt string expansion. */ int no_longjmp_on_fatal_error = 0; +/* Non-zero means to allow unmatched globbed filenames to expand to + a null file. */ +int allow_null_glob_expansion; + +/* Non-zero means to throw an error when globbing fails to match anything. */ +int fail_glob_expansion; + /* Extern functions and variables from different files. */ extern int last_command_exit_value, last_command_exit_signal; extern int subshell_environment, running_in_background; @@ -195,6 +202,10 @@ extern int expanding_redir; extern int tempenv_assign_error; extern int builtin_ignoring_errexit; +#if defined (ARRAY_VARS) +extern int assoc_expand_once; +#endif + #if defined (JOB_CONTROL) && defined (PROCESS_SUBSTITUTION) extern PROCESS *last_procsub_child; #endif @@ -203,13 +214,6 @@ extern PROCESS *last_procsub_child; extern wchar_t *wcsdup __P((const wchar_t *)); #endif -/* Non-zero means to allow unmatched globbed filenames to expand to - a null file. */ -int allow_null_glob_expansion; - -/* Non-zero means to throw an error when globbing fails to match anything. */ -int fail_glob_expansion; - #if 0 /* Variables to keep track of which words in an expanded word list (the output of expand_word_list_internal) are the result of globbing @@ -7150,7 +7154,7 @@ verify_substring_values (v, value, substr, vtype, e1p, e2p) t = (char *)0; temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES); - *e1p = evalexp (temp1, &expok); + *e1p = evalexp (temp1, 0, &expok); free (temp1); if (expok == 0) return (0); @@ -7208,7 +7212,7 @@ verify_substring_values (v, value, substr, vtype, e1p, e2p) temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES); free (temp2); t[-1] = ':'; - *e2p = evalexp (temp1, &expok); + *e2p = evalexp (temp1, 0, &expok); free (temp1); if (expok == 0) return (0); @@ -8959,7 +8963,7 @@ arithsub: /* No error messages. */ savecmd = this_command_name; this_command_name = (char *)NULL; - number = evalexp (temp1, &expok); + number = evalexp (temp1, 0, &expok); this_command_name = savecmd; free (temp); free (temp1); diff --git a/test.c b/test.c index 6b54e32f..3da8c7b3 100644 --- a/test.c +++ b/test.c @@ -344,10 +344,10 @@ arithcomp (s, t, op, flags) if (flags & TEST_ARITHEXP) { - l = evalexp (s, &expok); + l = evalexp (s, 0, &expok); if (expok == 0) return (FALSE); /* should probably longjmp here */ - r = evalexp (t, &expok); + r = evalexp (t, 0, &expok); if (expok == 0) return (FALSE); /* ditto */ } diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index d29259a9..554f3d6e 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -1,9 +1,12 @@ -BUILD_DIR=/usr/local/build/chet/bash/bash-current +BUILD_DIR=/usr/local/build/bash/bash-current THIS_SH=$BUILD_DIR/bash PATH=$PATH:$BUILD_DIR export THIS_SH PATH +: ${TMPDIR:=/tmp} +export TMPDIR + export BASH_TSTOUT=/tmp/xx rm -f ${BASH_TSTOUT} diff --git a/tests/shopt.right b/tests/shopt.right index 86d9ed6b..91fb073f 100644 --- a/tests/shopt.right +++ b/tests/shopt.right @@ -2,6 +2,7 @@ shopt: usage: shopt [-pqsu] [-o] [optname ...] -- shopt -u autocd +shopt -u assoc_expand_once shopt -u cdable_vars shopt -s cdspell shopt -u checkhash @@ -67,6 +68,7 @@ shopt -s promptvars shopt -s sourcepath -- shopt -u autocd +shopt -u assoc_expand_once shopt -u cdable_vars shopt -u checkhash shopt -u checkjobs @@ -105,6 +107,7 @@ shopt -u shift_verbose shopt -u xpg_echo -- autocd off +assoc_expand_once off cdable_vars off checkhash off checkjobs off diff --git a/tests/test.right b/tests/test.right index 7fcd9964..9832bd6d 100644 --- a/tests/test.right +++ b/tests/test.right @@ -289,3 +289,7 @@ t -t /dev/tty4 t -t /dev/tty4444444... 1 1 +t -p /dev/fd/6 +1 +t -p /dev/fd/6 +0 diff --git a/tests/test.tests b/tests/test.tests index 47eef354..07a87a0b 100644 --- a/tests/test.tests +++ b/tests/test.tests @@ -436,3 +436,5 @@ t -t /dev/tty4444444... # fixed in bash-4.0-beta t -t ' ' + +${THIS_SH} ./test1.sub diff --git a/tests/test1.sub b/tests/test1.sub new file mode 100644 index 00000000..2f4c2c0d --- /dev/null +++ b/tests/test1.sub @@ -0,0 +1,21 @@ +# some systems, like old SunOS, have stat on /dev/fd/N and fstat(N, ...) +# return different results +: ${TMPDIR:=/tmp} + +trap 'rm -f ${TMPDIR}/pipe}' 0 1 2 3 6 15 + +exec 6>&- +echo "t -p /dev/fd/6" +test -p /dev/fd/6 +echo $? + +rm -f ${TMPDIR}/pipe 2>/dev/null +mkfifo ${TMPDIR}/pipe +cat < ${TMPDIR}/pipe & +exec 6>&- +exec 6>${TMPDIR}/pipe +echo "t -p /dev/fd/6" +test -p /dev/fd/6 +echo $? +exec 2>/dev/null # disable process termination message +kill $! 2>/dev/null diff --git a/variables.c b/variables.c index ead80dd5..027b0ce8 100644 --- a/variables.c +++ b/variables.c @@ -2686,14 +2686,14 @@ make_variable_value (var, value, flags) if (flags & ASS_APPEND) { oval = value_cell (var); - lval = evalexp (oval, &expok); /* ksh93 seems to do this */ + lval = evalexp (oval, 0, &expok); /* ksh93 seems to do this */ if (expok == 0) { top_level_cleanup (); jump_to_top_level (DISCARD); } } - rval = evalexp (value, &expok); + rval = evalexp (value, 0, &expok); if (expok == 0) { top_level_cleanup ();