]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
change to readline callback signal handling; fix message when popping shell function...
authorChet Ramey <chet.ramey@case.edu>
Sat, 15 Oct 2022 17:34:51 +0000 (13:34 -0400)
committerChet Ramey <chet.ramey@case.edu>
Sat, 15 Oct 2022 17:34:51 +0000 (13:34 -0400)
15 files changed:
CWRU/CWRU.chlog
builtins/common.h
builtins/evalstring.c
builtins/shopt.def
execute_cmd.c
general.c
lib/readline/callback.c
parse.y
parser.h
shell.c
sig.c
subst.c
support/bash-logo-web.png [new file with mode: 0644]
tests/extglob.tests
variables.c

index b04fb2566c40e49f7ad2e7197773efe5b7e88a13..68a7d35db4c363c2ba1ecb1dcc82befcd27af94b 100644 (file)
@@ -4078,3 +4078,69 @@ execute_cmd.c
        - shell_execve: rearrange code so that we check for a bad interpreter
          before printing a generic ENOENT error message. Report from
          Kirill Elagin <kirelagin@gmail.com>
+
+                                  10/12
+                                  -----
+lib/readline/callback.c
+       - CALLBACK_READ_RETURN: add an inlined call to RL_CHECK_SIGNALS so we
+         can handle any signals that arrived before we restored the calling
+         application's signal handlers. From a gdb dicussion with
+         Simon Marchi <simon.marchi@polymtl.ca>
+
+                                  10/12
+                                  -----
+variables.c
+       - pop_var_context: flag an internal error for shell_variables not
+         pointing to a function context only if we haven't already flushed
+         all the local contexts and reset variable_context. This can happen
+         if errexit is enabled and we're going to be exiting the shell, but
+         we're running unwind-protects on our way out. Report from
+         Xavier Delaruelle <xavier.delaruelle@gmail.com>
+
+                                  10/13
+                                  -----
+sig.c
+       - kill_shell: broke the code that resets the signal disposition to the
+         default and sends a terminating signal to the shell into a separate
+         function
+       - termsig_handler: set handling_termsig to terminating_signal and make
+         it file-scope so other functions know we're handling a terminating
+         signal and are about to exit, and which signal it is (latter not used
+         yet)
+       - termsig_sighandler: if we get a fatal signal while we're handling a
+         fatal signal, kill ourselves with the second fatal signal immediately.
+         Fixes issue reported by Andreas Schwab <schwab@suse.de>
+
+execute_cmd.c
+       - execute_case_command: call CHECK_TERMSIG after the call to strmatch,
+         since gmatch will return FNM_NOMATCH if there's a pending terminating
+         signal and we don't want incorrect results
+
+subst.c
+       - pat_subst: make sure REP is non-NULL before calling savestring on it.
+         Report from Justin Wood (Callek) <callek@gmail.com>
+
+                                  10/14
+                                  -----
+builtins/{shopt.def,common.h}
+       - expand_aliases: split into a variable that holds the current state
+         of alias expansion (expand_aliases) and a variable that reflects the
+         global option value (expalias_flag), make sure expand_aliases is set
+         appropriately by shopt
+
+shell.c,execute_cmd.c,general.c
+       - expand_aliases: make sure expand_aliases and expalias_flag always
+         agree
+
+parser.h
+       - PST_STRING: new parser flag, set when parsing a string to a command
+         or word list
+
+parse.y
+       - reset_parser: if we're parsing a command substitution or a string,
+         and need to restore expand_aliases, make sure it's set to the value
+         of expalias_flag.
+         Fixes SIGINT during interactive command substitution parsing bug
+         reported by feng xiangjun <fengxj325@gmail.com>
+       - parse_string_to_word_list,parse_string_to_command: make sure to set
+         PST_STRING in parser_flags since we're resetting expand_aliases
index 543e4e0c05113ebe0ff6b3ddf8622ce406c9f5b7..726bd91fc37aec3fa8010dc4b2f213ea120337b8 100644 (file)
@@ -261,6 +261,8 @@ extern int expand_once_flag;
 extern int extglob_flag;
 #endif
 
+extern int expaliases_flag;
+
 /* variables from source.def */
 extern int source_searches_cwd;
 extern int source_uses_path;
index fd635299581f57369fe999365d998de6669f7edb..a4c263fda42e6c0891f9fb1d5bca362091f8f408 100644 (file)
@@ -590,6 +590,7 @@ parse_string (string, from_file, flags, cmdp, endp)
   char *ostring;
   volatile sigset_t ps_sigmask;
 
+  /* unwind-protects common to this and parse_and_execute */
   parse_prologue (string, flags, PS_TAG);
 
 #if defined (HAVE_POSIX_SIGNALS)
index 0a6a9b743a4463981918c15b452023e34fdcad18..0c9de8e66f5783a3b401433527d30512042d160f 100644 (file)
@@ -154,6 +154,9 @@ int extglob_flag = EXTGLOB_DEFAULT;
 static int shopt_set_extglob PARAMS((char *, int));
 #endif
 
+int expaliases_flag = 0;
+static int shopt_set_expaliases PARAMS((char *, int));
+
 static int shopt_set_debug_mode PARAMS((char *, int));
 
 static int shopt_login_shell;
@@ -203,7 +206,7 @@ static struct {
 #endif
   { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
   { "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL },
-  { "expand_aliases", &expand_aliases, (shopt_set_func_t *)NULL },
+  { "expand_aliases", &expaliases_flag, shopt_set_expaliases },
 #if defined (DEBUGGER)
   { "extdebug", &debugging_mode, shopt_set_debug_mode },
 #endif
@@ -355,7 +358,7 @@ reset_shopt_options ()
   check_window_size = CHECKWINSIZE_DEFAULT;
   allow_null_glob_expansion = glob_dot_filenames = 0;
   no_exit_on_failed_exec = 0;
-  expand_aliases = 0;
+  expand_aliases = expaliases_flag = 0;
   extended_quote = 1;
   fail_glob_expansion = 0;
   glob_asciirange = GLOBASCII_DEFAULT;
@@ -636,6 +639,15 @@ shopt_set_debug_mode (option_name, mode)
   return (0);
 }
 
+static int
+shopt_set_expaliases (option_name, mode)
+     char *option_name;
+     int mode;
+{
+  expand_aliases = expaliases_flag;
+  return 0;
+}
+
 #if defined (EXTENDED_GLOB)
 static int
 shopt_set_extglob (option_name, mode)
@@ -652,8 +664,6 @@ static int
 shopt_enable_hostname_completion (option_name, mode)
      char *option_name;
      int mode;
-
-
 {
   return (enable_hostname_completion (mode));
 }
index abb19b73c96fa9d030995a3d7e9e05242ec4ff78..b106645113eaae3f2100702565986db32340ac7c 100644 (file)
@@ -1539,7 +1539,7 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
         expansion with `shopt -s expand_alias' to continue to expand
         aliases. */
       if (ois != interactive_shell)
-       expand_aliases = 0;
+       expand_aliases = expaliases_flag = 0;
     }
 
   /* Subshells are neither login nor interactive. */
@@ -3627,6 +3627,7 @@ execute_case_command (case_command)
          free (pattern);
 
          dispose_words (es);
+         CHECK_TERMSIG;
 
          if (match)
            {
index 85c5a8b685908a432992bd5035c612398884a11a..2bc9f382af5aa4b2b010144c42fb876a32970e0d 100644 (file)
--- a/general.c
+++ b/general.c
@@ -91,7 +91,7 @@ static struct {
 {
   &interactive_comments,
   &source_uses_path,
-  &expand_aliases,
+  &expaliases_flag,
   &inherit_errexit,
   &print_shift_error,
   0
@@ -106,7 +106,8 @@ posix_initialize (on)
   /* Things that should be turned on when posix mode is enabled. */
   if (on != 0)
     {
-      interactive_comments = source_uses_path = expand_aliases = 1;
+      interactive_comments = source_uses_path = 1;
+      expand_aliases = expaliases_flag = 1;
       inherit_errexit = 1;
       source_searches_cwd = 0;
       print_shift_error = 1;
@@ -116,13 +117,14 @@ posix_initialize (on)
   else if (saved_posix_vars)           /* on == 0, restore saved settings */
     {
       set_posix_options (saved_posix_vars);
+      expand_aliases = expaliases_flag;
       free (saved_posix_vars);
       saved_posix_vars = 0;
     }
   else /* on == 0, restore a default set of settings */
     {
       source_searches_cwd = 1;
-      expand_aliases = interactive_shell;
+      expand_aliases = expaliases_flag = interactive_shell;    /* XXX */
       print_shift_error = 0;
     }
 }
index 69df77df709590dcbbec9f05c263d96826f0411a..d78a7ca77c5078c39cf9617ddcc45eca68e63298 100644 (file)
@@ -115,7 +115,10 @@ rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *linefunc)
 #define CALLBACK_READ_RETURN() \
   do { \
     if (rl_persistent_signal_handlers == 0) \
-      rl_clear_signals (); \
+      { \
+       rl_clear_signals (); \
+       if (_rl_caught_signal) _rl_signal_handler (_rl_caught_signal); \
+      } \
     return; \
   } while (0)
 #else
diff --git a/parse.y b/parse.y
index 75904eeaa0e173e890127f6922c1624cf2faa458..07d788b44367edb6740680c82bf8fcbf11daaa53 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -3306,6 +3306,8 @@ reset_parser ()
   if (parser_state & (PST_EXTPAT|PST_CMDSUBST))
     extended_glob = extglob_flag;
 #endif
+  if (parser_state & (PST_CMDSUBST|PST_STRING))
+    expand_aliases = expaliases_flag;
 
   parser_state = 0;
   here_doc_first_line = 0;
@@ -4392,6 +4394,7 @@ parse_string_to_command (string, flags)
   if (flags & SX_COMPLETE)
     parser_state |= PST_NOERROR;
 
+  parser_state |= PST_STRING;
   expand_aliases = 0;
 
   cmd = 0;
@@ -6409,7 +6412,7 @@ parse_string_to_word_list (s, flags, whom)
       /* State flags we don't want to persist into compound assignments. */
       parser_state &= ~PST_NOEXPAND;   /* parse_comsub sentinel */
       /* State flags we want to set for this run through the tokenizer. */
-      parser_state |= PST_COMPASSIGN|PST_REPARSE;
+      parser_state |= PST_COMPASSIGN|PST_REPARSE|PST_STRING;
     }
 
   while ((tok = read_token (READ)) != yacc_EOF)
index 59bf0fec4c427cdd4d009e8319f84e2d762b4ccc..cae3a35f7f10f6b4b16c02874446195a13d1e691 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -50,6 +50,7 @@
 #define PST_ENDALIAS   0x200000        /* just finished expanding and consuming an alias */
 #define PST_NOEXPAND   0x400000        /* don't expand anything in read_token_word; for command substitution */
 #define PST_NOERROR    0x800000        /* don't print error messages in yyerror */
+#define PST_STRING     0x1000000       /* parsing a string to a command or word list */
 
 /* Definition of the delimiter stack.  Needed by parse.y and bashhist.c. */
 struct dstack {
diff --git a/shell.c b/shell.c
index ee9d445d20cc0eae807800a92ecab96045262300..ebd89651efc90f8fa09cf1774bb20de184a21b6f 100644 (file)
--- a/shell.c
+++ b/shell.c
@@ -1844,8 +1844,8 @@ reset_option_defaults ()
 static void
 init_interactive ()
 {
-  expand_aliases = interactive_shell = startup_state = 1;
-  interactive = 1;
+  expand_aliases = expaliases_flag = 1;
+  interactive_shell = startup_state = interactive = 1;
 #if defined (HISTORY)
   if (enable_history_list == -1)
     enable_history_list = 1;                           /* set default  */
@@ -1865,7 +1865,7 @@ init_noninteractive ()
   bash_history_reinit (0);
 #endif /* HISTORY */
   interactive_shell = startup_state = interactive = 0;
-  expand_aliases = posixly_correct;    /* XXX - was 0 not posixly_correct */
+  expand_aliases = expaliases_flag = posixly_correct;  /* XXX - was 0 not posixly_correct */
   no_line_editing = 1;
 #if defined (JOB_CONTROL)
   /* Even if the shell is not interactive, enable job control if the -i or
@@ -1882,7 +1882,7 @@ init_interactive_script ()
     enable_history_list = 1;
 #endif
   init_noninteractive ();
-  expand_aliases = interactive_shell = startup_state = 1;
+  expand_aliases = expaliases_flag = interactive_shell = startup_state = 1;
 #if defined (HISTORY)
   remember_on_history = enable_history_list;   /* XXX */
 #endif
@@ -2025,7 +2025,7 @@ shell_reinitialize ()
   debugging = do_version = line_number = last_command_exit_value = 0;
   forced_interactive = interactive_shell = 0;
   subshell_environment = running_in_background = 0;
-  expand_aliases = 0;
+  expand_aliases = expaliases_flag = 0;
   bash_argv_initialized = 0;
 
   /* XXX - should we set jobs_m_flag to 0 here? */
diff --git a/sig.c b/sig.c
index 840d577546d9197795521e92f32b0fd5a0cb2ac9..0d31cb4fcc4ee0e56b2a560913d94276bace7181 100644 (file)
--- a/sig.c
+++ b/sig.c
@@ -94,6 +94,7 @@ static SigHandler *old_winch = (SigHandler *)SIG_DFL;
 #endif
 
 static void initialize_shell_signals PARAMS((void));
+static void kill_shell PARAMS((int));
 
 void
 initialize_signals (reinit)
@@ -486,6 +487,8 @@ restore_sigmask ()
 #endif
 }
 
+static int handling_termsig = 0;
+
 sighandler
 termsig_sighandler (sig)
      int sig;
@@ -532,6 +535,14 @@ termsig_sighandler (sig)
    sig == terminating_signal)
     terminate_immediately = 1;
 
+  /* If we are currently handling a terminating signal, we have a couple of
+     choices here. We can ignore this second terminating signal and let the
+     shell exit from the first one, or we can exit immediately by killing
+     the shell with this signal. This code implements the latter; to implement
+     the former, replace the kill_shell(sig) with return. */
+  if (handling_termsig)
+    kill_shell (sig);          /* just short-circuit now */
+
   terminating_signal = sig;
 
   if (terminate_immediately)
@@ -564,16 +575,13 @@ void
 termsig_handler (sig)
      int sig;
 {
-  static int handling_termsig = 0;
-  int i, core;
-  sigset_t mask;
-
   /* Simple semaphore to keep this function from being executed multiple
      times.  Since we no longer are running as a signal handler, we don't
      block multiple occurrences of the terminating signals while running. */
   if (handling_termsig)
     return;
-  handling_termsig = 1;
+
+  handling_termsig = terminating_signal;       /* for termsig_sighandler */
   terminating_signal = 0;      /* keep macro from re-testing true. */
 
   /* I don't believe this condition ever tests true. */
@@ -613,6 +621,16 @@ termsig_handler (sig)
 
   run_exit_trap ();    /* XXX - run exit trap possibly in signal context? */
 
+  kill_shell (sig);
+}
+
+static void
+kill_shell (sig)
+     int sig;
+{
+  int i, core;
+  sigset_t mask;
+
   /* We don't change the set of blocked signals. If a user starts the shell
      with a terminating signal blocked, we won't get here (and if by some
      magic chance we do, we'll exit below). What we do is to restore the
@@ -627,7 +645,7 @@ termsig_handler (sig)
   if (dollar_dollar_pid != 1)
     exit (128+sig);            /* just in case the kill fails? */
 
-  /* We get here only under extraordinary circumstances. */
+  /* We get here only under extraordinarily rare circumstances. */
 
   /* We are PID 1, and the kill above failed to kill the process. We assume
      this means that we are running as an init process in a pid namespace
diff --git a/subst.c b/subst.c
index 51fd6468f248315fa71792d6c4f058e11f8c5c84..b778526a1a356d758796ae889f3b3f6d93dcdc53 100644 (file)
--- a/subst.c
+++ b/subst.c
@@ -4005,7 +4005,7 @@ expand_string_for_patsub (string, quoted)
   if (value)
     {
       t = (value->next) ? string_list (value) : value->word->word;
-      ret = quote_string_for_repl (t, quoted);
+      ret = t ? quote_string_for_repl (t, quoted) : t;
       if (t != value->word->word)
        free (t);
       dispose_words (value);
@@ -8970,7 +8970,8 @@ pat_subst (string, pat, rep, mflags)
       return (ret);
     }
   else if (*string == 0 && (match_pattern (string, pat, mtype, &s, &e) != 0))
-    return ((mflags & MATCH_EXPREP) ? strcreplace (rep, '&', "", 2) : savestring (rep));
+    return (mflags & MATCH_EXPREP) ? strcreplace (rep, '&', "", 2)
+                                  : (rep ? savestring (rep) : savestring (""));
 
   ret = (char *)xmalloc (rsize = 64);
   ret[0] = '\0';
diff --git a/support/bash-logo-web.png b/support/bash-logo-web.png
new file mode 100644 (file)
index 0000000..e8744fe
Binary files /dev/null and b/support/bash-logo-web.png differ
index f13e8fb62287aa3b8f299f01ec67bd0a1e05f4fe..ef5d7793c1fac66e8d9dbec362bd86d6a2e30abc 100644 (file)
@@ -379,6 +379,11 @@ shopt -u globstar
 # in the right place
 builtin cd "$MYDIR"
 
+# seg fault in bash-5.2
+foo=
+foo=${foo/#*([.])}
+unset foo
+
 ${THIS_SH} ./extglob1.sub
 ${THIS_SH} ./extglob1a.sub
 ${THIS_SH} ./extglob3.sub
index 1a0c2c45c053fcce715ba2fa9095c41488994e70..84af3c6359a30b48e605f85d478bb8a10a0539cc 100644 (file)
@@ -5413,7 +5413,9 @@ pop_var_context ()
   vcxt = shell_variables;
   if (vc_isfuncenv (vcxt) == 0)
     {
-      internal_error (_("pop_var_context: head of shell_variables not a function context"));
+      /* If we haven't flushed all of the local contexts already, flag an error */
+      if (shell_variables != global_variables || variable_context > 0)
+       internal_error (_("pop_var_context: head of shell_variables not a function context"));
       return;
     }