minor fixes to command -p, posix-mode tilde expansion, line numbers when in ERR traps

This commit is contained in:
Chet Ramey
2021-11-04 15:45:55 -04:00
parent 4657c04050
commit b06200f7a1
6 changed files with 121 additions and 27 deletions
+41
View File
@@ -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 <roger.morris@gmail.com>
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
<andersk@mit.edu>
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 <quinn@quinngrier.com>
Vendored
+21 -6
View File
@@ -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 <inttypes.h>. 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
Vendored
+20 -7
View File
@@ -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);
+30 -8
View File
@@ -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;
+8 -6
View File
@@ -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);
+1
View File
@@ -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);