]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
minor fixes to command -p, posix-mode tilde expansion, line numbers when in ERR traps
authorChet Ramey <chet.ramey@case.edu>
Thu, 4 Nov 2021 19:45:55 +0000 (15:45 -0400)
committerChet Ramey <chet.ramey@case.edu>
Thu, 4 Nov 2021 19:45:55 +0000 (15:45 -0400)
CWRU/CWRU.chlog
aclocal.m4
configure
execute_cmd.c
findcmd.c
subst.c

index 18118ccfeac70f7adde35c0b2b26dba7db472c7f..fecad1647ec3fbc3a4bfa2476c29cc8d2dcfd5a1 100644 (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>
index e9fca71401ff31ae2f21f615a9692478055ff566..15d914338131add7afc428603b3aaf9fc7de64a1 100644 (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
index 1ca66828bd374bb673da7feecb8d734da3e5d919..27df47a8c68cc3953a21bc86e02271e95692dcf3 100755 (executable)
--- 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);
 
index 964093c1bdc127fca9b0892f9ec60c9e6108f78b..0ef8bfddbc78182515cebe40789244f6a34a9fef 100644 (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;
 
index a4e679b80f8dded14dad31493bc74f26b841625b..30e5595481ce0aa9695c10b36949da5f742d718b 100644 (file)
--- 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 73c67f888a9a4bbdbcaa5d5d02b8cb3dde261f1d..53b8844c65aecf3c5059f5d46ba96b14e18318bb 100644 (file)
--- 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);