From: Chet Ramey Date: Thu, 4 Nov 2021 19:45:55 +0000 (-0400) Subject: minor fixes to command -p, posix-mode tilde expansion, line numbers when in ERR traps X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b06200f7a1e1d7e1ffe39bb035dc761a9a204f1a;p=thirdparty%2Fbash.git minor fixes to command -p, posix-mode tilde expansion, line numbers when in ERR traps --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 18118ccfe..fecad1647 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -2400,3 +2400,44 @@ subst.c newly-allocated memory in case it gets freed on error during the call to call_expand_word_internal(); free it manually when that call returns + + 11/1 + ---- +findcmd.c + - search_for_command: if FLAGS includes CMDSRCH_STDPATH, don't look in + the hash table for the command name. Prompted by a report from + Roger Morris + +aclocal.m4 + - BASH_FUNC_POSIX_SETJMP: add a check by fetching the signal mask + after the siglongjmp and making sure that SIGINT is not blocked, + indicating we restored the original signal mask + + 11/2 + ---- +subst.c + - expand_string_assignment: make sure to add W_TILDEEXP to the flags so + expand_word_internal performs the right tilde expansion on tildes + following an unquoted colon. Report from Anders Kaseorg + + + + 11/3 + ---- +aclocal.m4 + - BASH_FUNC_POSIX_SETJMP: if cross-compiling, default to `present' if + we've determined we have posix signal functions + + 11/4 + ---- +execute_cmd.c + - SET_LINE_NUMBER: set line_number, but don't set line_number_for_err_trap + if we're already running the ERR trap + - GET_LINE_NUMBER: evaluates to line_number_for_err_trap if we're + running the ERR trap and executing_line_number() otherwise + - execute_function: use GET_LINE_NUMBER to push the value for the line + number into the BASH_LINENO array + - execute_command_internal,execute_arith_command,execute_cond_command: + use SET_LINE_NUMBER to avoid overwriting line_number_for_err trap + while executing the ERR trap. Tentative fix for `caller' problem + reported by Quinn Grier diff --git a/aclocal.m4 b/aclocal.m4 index e9fca7140..15d914338 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -3,6 +3,8 @@ dnl Bash specific tests dnl dnl Some derived from PDKSH 5.1.3 autoconf tests dnl +dnl Copyright (C) 1987-2021 Free Software Foundation, Inc. +dnl dnl dnl Check for . This is separated out so that it can be @@ -781,21 +783,30 @@ exit (1); #else int code; -sigset_t set, oset; +sigset_t set, oset, nset; sigjmp_buf xx; /* get the mask */ sigemptyset(&set); sigemptyset(&oset); -sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &set); + sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &oset); +/* paranoia -- make sure SIGINT is not blocked */ +sigdelset (&oset, SIGINT); +sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL); /* save it */ code = sigsetjmp(xx, 1); if (code) - exit(0); /* could get sigmask and compare to oset here. */ +{ + sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &nset); + /* could compare nset to oset here, but we just look for SIGINT */ + if (sigismember (&nset, SIGINT)) + exit(1); + exit(0); +} -/* change it */ +/* change it so that SIGINT is blocked */ sigaddset(&set, SIGINT); sigprocmask(SIG_BLOCK, &set, (sigset_t *)NULL); @@ -805,8 +816,12 @@ exit(1); #endif } ]])], [bash_cv_func_sigsetjmp=present], [bash_cv_func_sigsetjmp=missing], - [AC_MSG_WARN(cannot check for sigsetjmp/siglongjmp if cross-compiling -- defaulting to missing) - bash_cv_func_sigsetjmp=missing] + [AC_MSG_WARN(cannot check for sigsetjmp/siglongjmp if cross-compiling -- defaulting to $bash_cv_posix_signals) + if test "$bash_cv_posix_signals" = "yes" ; then + bash_cv_func_sigsetjmp=present + else + bash_cv_func_sigsetjmp=missing + fi] )]) AC_MSG_RESULT($bash_cv_func_sigsetjmp) if test $bash_cv_func_sigsetjmp = present; then diff --git a/configure b/configure index 1ca66828b..27df47a8c 100755 --- a/configure +++ b/configure @@ -20107,9 +20107,13 @@ then : else $as_nop if test "$cross_compiling" = yes then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cannot check for sigsetjmp/siglongjmp if cross-compiling -- defaulting to missing" >&5 -printf "%s\n" "$as_me: WARNING: cannot check for sigsetjmp/siglongjmp if cross-compiling -- defaulting to missing" >&2;} - bash_cv_func_sigsetjmp=missing + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cannot check for sigsetjmp/siglongjmp if cross-compiling -- defaulting to $bash_cv_posix_signals" >&5 +printf "%s\n" "$as_me: WARNING: cannot check for sigsetjmp/siglongjmp if cross-compiling -- defaulting to $bash_cv_posix_signals" >&2;} + if test "$bash_cv_posix_signals" = "yes" ; then + bash_cv_func_sigsetjmp=present + else + bash_cv_func_sigsetjmp=missing + fi else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20131,21 +20135,30 @@ exit (1); #else int code; -sigset_t set, oset; +sigset_t set, oset, nset; sigjmp_buf xx; /* get the mask */ sigemptyset(&set); sigemptyset(&oset); -sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &set); + sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &oset); +/* paranoia -- make sure SIGINT is not blocked */ +sigdelset (&oset, SIGINT); +sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL); /* save it */ code = sigsetjmp(xx, 1); if (code) - exit(0); /* could get sigmask and compare to oset here. */ +{ + sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &nset); + /* could compare nset to oset here, but we just look for SIGINT */ + if (sigismember (&nset, SIGINT)) + exit(1); + exit(0); +} -/* change it */ +/* change it so that SIGINT is blocked */ sigaddset(&set, SIGINT); sigprocmask(SIG_BLOCK, &set, (sigset_t *)NULL); diff --git a/execute_cmd.c b/execute_cmd.c index 964093c1b..0ef8bfddb 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -280,6 +280,23 @@ static int connection_count; can save and restore it. */ int line_number_for_err_trap; +/* A convenience macro to avoid resetting line_number_for_err_trap while + running the ERR trap. */ +#define SET_LINE_NUMBER(v) \ +do { \ + line_number = v; \ + if (signal_in_progress (ERROR_TRAP) == 0 && running_trap != (ERROR_TRAP + 1)) \ + line_number_for_err_trap = line_number; \ +} while (0) + +/* This can't be in executing_line_number() because that's used for LINENO + and we want LINENO to reflect the line number of commands run during + the ERR trap. Right now this is only used to push to BASH_LINENO. */ +#define GET_LINE_NUMBER() \ + (signal_in_progress (ERROR_TRAP) && running_trap == ERROR_TRAP+1) \ + ? line_number_for_err_trap \ + : executing_line_number () + /* A sort of function nesting level counter */ int funcnest = 0; int funcnest_max = 0; @@ -628,7 +645,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out, control and call execute_command () on the command again. */ save_line_number = line_number; if (command->type == cm_subshell) - line_number_for_err_trap = line_number = command->value.Subshell->line; /* XXX - save value? */ + SET_LINE_NUMBER (command->value.Subshell->line); /* XXX - save value? */ /* Otherwise we defer setting line_number */ tcmd = make_command_string (command); fork_flags = asynchronous ? FORK_ASYNC : 0; @@ -842,7 +859,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out, if (command->flags & CMD_STDIN_REDIR) command->value.Simple->flags |= CMD_STDIN_REDIR; - line_number_for_err_trap = line_number = command->value.Simple->line; + SET_LINE_NUMBER (command->value.Simple->line); exec_result = execute_simple_command (command->value.Simple, pipe_in, pipe_out, asynchronous, fds_to_close); @@ -1042,7 +1059,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out, command->value.Cond->flags |= CMD_IGNORE_RETURN; #endif - line_number_for_err_trap = save_line_number = line_number; + line_number_for_err_trap = save_line_number = line_number; /* XXX */ #if defined (DPAREN_ARITHMETIC) if (command->type == cm_arith) exec_result = execute_arith_command (command->value.Arith); @@ -2751,7 +2768,7 @@ execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close) invert = (command->flags & CMD_INVERT_RETURN) != 0; ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0; - line_number_for_err_trap = line_number; /* XXX - save value? */ + SET_LINE_NUMBER (line_number); /* XXX - save value? */ exec_result = execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close); if (asynchronous) @@ -3772,7 +3789,7 @@ execute_arith_command (arith_command) save_line_number = line_number; this_command_name = "(("; /* )) */ - line_number_for_err_trap = line_number = arith_command->line; + SET_LINE_NUMBER (arith_command->line); /* If we're in a function, update the line number information. */ if (variable_context && interactive_shell && sourcelevel == 0) { @@ -4015,7 +4032,7 @@ execute_cond_command (cond_command) save_line_number = line_number; this_command_name = "[["; - line_number_for_err_trap = line_number = cond_command->line; + SET_LINE_NUMBER (cond_command->line); /* If we're in a function, update the line number information. */ if (variable_context && interactive_shell && sourcelevel == 0) { @@ -5023,7 +5040,7 @@ execute_function (var, words, flags, fds_to_close, async, subshell) struct fd_bitmap *fds_to_close; int async, subshell; { - int return_val, result; + int return_val, result, lineno; COMMAND *tc, *fc, *save_current; char *debug_trap, *error_trap, *return_trap; #if defined (ARRAY_VARS) @@ -5151,7 +5168,8 @@ execute_function (var, words, flags, fds_to_close, async, subshell) array_push ((ARRAY *)funcname_a, this_shell_function->name); array_push ((ARRAY *)bash_source_a, sfile); - t = itos (executing_line_number ()); + lineno = GET_LINE_NUMBER (); + t = itos (lineno); array_push ((ARRAY *)bash_lineno_a, t); free (t); #endif @@ -5609,6 +5627,10 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out, } #endif /* RESTRICTED_SHELL */ + /* If we want to change this so `command -p' (CMD_STDPATH) does not insert + any pathname it finds into the hash table, it should read + command = search_for_command (pathname, stdpath ? CMDSRCH_STDPATH : CMDSRCH_HASH); + */ command = search_for_command (pathname, CMDSRCH_HASH|(stdpath ? CMDSRCH_STDPATH : 0)); QUIT; diff --git a/findcmd.c b/findcmd.c index a4e679b80..30e559548 100644 --- a/findcmd.c +++ b/findcmd.c @@ -1,6 +1,6 @@ /* findcmd.c -- Functions to search for commands by name. */ -/* Copyright (C) 1997-2020 Free Software Foundation, Inc. +/* Copyright (C) 1997-2021 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -328,9 +328,9 @@ get_next_path_element (path_list, path_index_pointer) /* Look for PATHNAME in $PATH. Returns either the hashed command corresponding to PATHNAME or the first instance of PATHNAME found in $PATH. If (FLAGS&CMDSRCH_HASH) is non-zero, insert the instance of - PATHNAME found in $PATH into the command hash table. If (FLAGS&CMDSRCH_STDPATH) - is non-zero, we are running in a `command -p' environment and should use - the Posix standard path. + PATHNAME found in $PATH into the command hash table. + If (FLAGS&CMDSRCH_STDPATH) is non-zero, we are running in a `command -p' + environment and should use the Posix standard path. Returns a newly-allocated string. */ char * search_for_command (pathname, flags) @@ -351,7 +351,7 @@ search_for_command (pathname, flags) /* Don't waste time trying to find hashed data for a pathname that is already completely specified or if we're using a command- specific value for PATH. */ - if (temp_path == 0 && absolute_program (pathname) == 0) + if (temp_path == 0 && (flags & CMDSRCH_STDPATH) == 0 && absolute_program (pathname) == 0) hashed_file = phash_search (pathname); /* If a command found in the hash table no longer exists, we need to @@ -390,7 +390,7 @@ search_for_command (pathname, flags) { /* If we found the full pathname the same as the command name, the command probably doesn't exist. Don't put it into the hash - table. */ + table unless it's an executable file in the current directory. */ if (STREQ (command, pathname)) { st = file_status (command); @@ -536,6 +536,8 @@ find_in_path_element (name, path, flags, name_len, dotinfop) /* Remember the location of "." in the path, in all its forms (as long as they begin with a `.', e.g. `./.') */ + /* We could also do this or something similar for all relative pathnames + found while searching PATH. */ if (dot_found_in_search == 0 && *xpath == '.') dot_found_in_search = same_file (".", xpath, dotinfop, (struct stat *)NULL); diff --git a/subst.c b/subst.c index 73c67f888..53b8844c6 100644 --- a/subst.c +++ b/subst.c @@ -3953,6 +3953,7 @@ expand_string_assignment (string, quoted) #else td.flags = W_ASSIGNRHS; #endif + td.flags |= (W_NOGLOB|W_TILDEEXP); td.word = savestring (string); value = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL); FREE (td.word);