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>
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
#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);
#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
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
#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);
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;
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;
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);
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);
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)
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)
{
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)
{
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)
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
}
#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;
/* 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.
/* 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)
/* 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
{
/* 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);
/* 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);
#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);