]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
fix for exit builtin when ignoreeof set; better resource deallocation when completion...
authorChet Ramey <chet.ramey@case.edu>
Mon, 26 Jun 2023 21:09:08 +0000 (17:09 -0400)
committerChet Ramey <chet.ramey@case.edu>
Mon, 26 Jun 2023 21:09:08 +0000 (17:09 -0400)
CWRU/CWRU.chlog
eval.c
examples/loadables/getconf.c
lib/glob/glob.c
lib/readline/complete.c
lib/readline/rltypedefs.h
lib/readline/signals.c
print_cmd.c

index cb9fb332717da7aed89d8053dc5b9f8341365a9e..2dfd28d1fee2b2436d751ebc022eceba8af18f15 100644 (file)
@@ -6875,4 +6875,46 @@ examples/loadables/{kv,stat}.c
 lib/readline/complete.c
        - rl_menu_complete: use _rl_free_match_list instead of just freeing
          MATCHES if we have too many possible completions to display.
+         From a report by Grisha Levit <grishalevit@gmail.com>
+
+                                  6/25
+                                  ----
+eval.c
+       - reader_loop: make sure to allow exit builtin (code == EXITBLTIN) to
+         exit the shell when ignoreeof is set
+         From a report by Grisha Levit <grishalevit@gmail.com>
+
+                                  6/26
+                                  ----
+lib/readline/complete.c
+       - complete_sigcleanarg_t: new struct to hold match list and saved line
+         buffer for cleanup on receipt of SIGINT
+       - _rl_complete_sigcleanup: use new sigcleanarg_t struct and free both
+         members
+       - rl_complete_internal: whenever we display the match list, set up to
+         clean the matches and saved line buffer in the event of a SIGINT
+         From a report by Grisha Levit <grishalevit@gmail.com>
+
+lib/readline/signals.c
+       - _rl_handle_signal: if readline is compiled to include callbacks, only
+         call rl_echo_signal_char if we're not in callback mode or the
+         application has set rl_persistent_signal_handlers, leaving any
+         application signal handler to call it (or not) otherwise.
+         From a discussion with Andrew Burgess <aburgess@redhat.com>
+
+lib/glob/glob.c
+       - glob_filename: if ARRAY == TEMP_RESULTS, make sure to free TEMP_RESULTS
+         after copying the filenames out of ARRAY, since we either assigned it
+         directly or glob_dir_to_array returned it because the dirname was
+         the empty string.
+         From a report by Grisha Levit <grishalevit@gmail.com>
+
+lib/readline/rltypedefs.h
+       - Function: only compile in these obsolete typedefs if
+         WANT_OBSOLETE_TYPEDEFS is defined
+
+print_cmd.c
+       - xtrace_print_assignment,xtrace_print_word_list: prioritize checking
+         for characters that need $'...' printing over shell metacharacters
+         so that strings containing both get the $'...' treatment
          From a report by Grisha Levit <grishalevit@gmail.com>
diff --git a/eval.c b/eval.c
index 8337a275f85e9ada84c4c4922f43f9afe854052d..2f5d1fbec8a216c85d0cc7cc823d2f7722ae58e0 100644 (file)
--- a/eval.c
+++ b/eval.c
@@ -183,7 +183,7 @@ reader_loop (void)
                  current_command = (COMMAND *)NULL;
                }
            }
-         if (EOF_Reached && interactive && ignoreeof && parse_and_execute_level == 0)
+         if (EOF_Reached && interactive && ignoreeof && parse_and_execute_level == 0 && code != EXITBLTIN)
            {
              if (handle_ignoreeof (1))
                EOF_Reached = 0;
index 27a04dcfd23e2e31d0c8ba23ade2dbc1ebaf474b..af5544f0b6981e18e0210dcda72687bf67c29efa 100644 (file)
@@ -274,9 +274,13 @@ static const struct conf vars[] =
 #ifdef _SC_AVPHYS_PAGES
     { "_AVPHYS_PAGES", _SC_AVPHYS_PAGES, SYSCONF },
 #endif
+#ifdef _NPROCESSORS_CONF
     { "_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF, SYSCONF },
     { "_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN, SYSCONF },
+#endif
+#ifdef _PHYS_PAGES
     { "_PHYS_PAGES", _SC_PHYS_PAGES, SYSCONF },
+#endif
 #ifdef _SC_ARG_MAX
     { "_POSIX_ARG_MAX", _SC_ARG_MAX, SYSCONF },
 #else
@@ -859,7 +863,9 @@ static const struct conf vars[] =
     { "SEM_VALUE_MAX", _SC_SEM_VALUE_MAX, SYSCONF },
 #endif
     { "SIGQUEUE_MAX", _SC_SIGQUEUE_MAX, SYSCONF },
+#ifdef _PC_FILESIZEBITS
     { "FILESIZEBITS", _PC_FILESIZEBITS, PATHCONF },
+#endif
 #ifdef _PC_ALLOC_SIZE_MIN
     { "POSIX_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN, PATHCONF },
 #endif
@@ -875,7 +881,9 @@ static const struct conf vars[] =
 #ifdef _PC_REC_XFER_ALIGN
     { "POSIX_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN, PATHCONF },
 #endif
+#ifdef _PC_SYMLINK_MAX
     { "SYMLINK_MAX", _PC_SYMLINK_MAX, PATHCONF },
+#endif
 #ifdef _PC_2_SYMLINKS
     { "POSIX2_SYMLINKS", _PC_2_SYMLINKS, PATHCONF },
 #endif
index c8027aadc39bc0fbc9e9075c27a2d90967ec9122..2227cd9803f4eec966a9838d5c125b5d4993e050 100644 (file)
@@ -1402,6 +1402,12 @@ glob_filename (char *pathname, int flags)
                free ((char *) array);
              else if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0')
                free (temp_results);    /* expanding ** case above */
+             else if (array == temp_results)
+               /* If array == temp_results, either we assigned it above or
+                  glob_dir_to_array returned temp_results because the dirname
+                  was the empty string. In any case, we assume temp_results
+                  has not been freed, and free it here. */
+               free (temp_results);
 
              if (shouldbreak)
                break;
@@ -1517,6 +1523,7 @@ only_filename:
 
       if (free_dirname)
        free (directory_name);
+
       return (result);
     }
 
index 05779f9741c34918f9662b999da03c100d027d3d..349c87a1f0e19d3dbb6d39f0e211e87ee22c1523 100644 (file)
@@ -489,6 +489,32 @@ rl_completion_mode (rl_command_func_t *cfunc)
     return TAB;
 }
 
+/********************************************/
+/*                                         */
+/*  Completion signal handling and cleanup  */
+/*                                         */
+/********************************************/
+
+/* State to clean up and free if completion is interrupted by a signal. */
+typedef struct {
+  char **matches;
+  char *saved_line;
+} complete_sigcleanarg_t;
+
+static void
+_rl_complete_sigcleanup (int sig, void *ptr)
+{
+  complete_sigcleanarg_t *arg;
+
+  if (sig == SIGINT)   /* XXX - for now */
+    {
+      arg = ptr;
+      _rl_free_match_list (arg->matches);
+      FREE (arg->saved_line);
+      _rl_complete_display_matches_interrupt = 1;
+    }
+}
+
 /************************************/
 /*                                 */
 /*    Completion utility functions  */
@@ -503,16 +529,6 @@ _rl_reset_completion_state (void)
   rl_completion_quote_character = 0;
 }
 
-static void
-_rl_complete_sigcleanup (int sig, void *ptr)
-{
-  if (sig == SIGINT)   /* XXX - for now */
-    {
-      _rl_free_match_list ((char **)ptr);
-      _rl_complete_display_matches_interrupt = 1;
-    }
-}
-
 /* Set default values for readline word completion.  These are the variables
    that application completion functions can change or inspect. */
 static void
@@ -2010,10 +2026,11 @@ rl_complete_internal (int what_to_do)
 {
   char **matches;
   rl_compentry_func_t *our_func;
-  int start, end, delimiter, found_quote, i, nontrivial_lcd;
+  int start, end, delimiter, found_quote, i, nontrivial_lcd, do_display;
   char *text, *saved_line_buffer;
   char quote_char;
   int tlen, mlen, saved_last_completion_failed;
+  complete_sigcleanarg_t cleanarg;     /* state to clean up on signal */
 
   RL_SETSTATE(RL_STATE_COMPLETING);
 
@@ -2092,6 +2109,8 @@ rl_complete_internal (int what_to_do)
   if (matches && matches[0] && *matches[0])
     last_completion_failed = 0;
 
+  do_display = 0;
+
   switch (what_to_do)
     {
     case TAB:
@@ -2125,13 +2144,13 @@ rl_complete_internal (int what_to_do)
        {
          if (what_to_do == '!')
            {
-             display_matches (matches);
+             do_display = 1;
              break;
            }
          else if (what_to_do == '@')
            {
              if (nontrivial_lcd == 0)
-               display_matches (matches);
+               do_display = 1;
              break;
            }
          else if (rl_editing_mode != vi_mode)
@@ -2156,22 +2175,7 @@ rl_complete_internal (int what_to_do)
          break;
        }
       
-      if (rl_completion_display_matches_hook == 0)
-       {
-         _rl_sigcleanup = _rl_complete_sigcleanup;
-         _rl_sigcleanarg = matches;
-         _rl_complete_display_matches_interrupt = 0;
-       }
-      display_matches (matches);
-      if (_rl_complete_display_matches_interrupt)
-        {
-          matches = 0;         /* already freed by rl_complete_sigcleanup */
-          _rl_complete_display_matches_interrupt = 0;
-         if (rl_signal_event_hook)
-           (*rl_signal_event_hook) ();         /* XXX */
-        }
-      _rl_sigcleanup = 0;
-      _rl_sigcleanarg = 0;
+      do_display = 1;
       break;
 
     default:
@@ -2184,6 +2188,34 @@ rl_complete_internal (int what_to_do)
       return 1;
     }
 
+  /* If we need to display the match list, set up to clean it up on receipt of
+     a signal and do it here. If the application has registered a function to
+     display the matches, let it do the work. */
+  if (do_display)
+    {
+      if (rl_completion_display_matches_hook == 0)
+       {
+         _rl_sigcleanup = _rl_complete_sigcleanup;
+         cleanarg.matches = matches;
+         cleanarg.saved_line = saved_line_buffer;
+         _rl_sigcleanarg = &cleanarg;
+         _rl_complete_display_matches_interrupt = 0;
+       }
+
+      display_matches (matches);
+
+      if (_rl_complete_display_matches_interrupt)
+       {
+         matches = 0;          /* Both already freed by _rl_complete_sigcleanup */
+         saved_line_buffer = 0;
+         _rl_complete_display_matches_interrupt = 0;
+         if (rl_signal_event_hook)
+           (*rl_signal_event_hook) ();
+       }
+      _rl_sigcleanup = 0;
+      _rl_sigcleanarg = 0;
+    }
+
   _rl_free_match_list (matches);
 
   /* Check to see if the line has changed through all of this manipulation. */
index b1ffeb05c4f4fb8744658843feab9abb70b5e971..d179e858f17605d2eaaf2413f821258db3cd6ceb 100644 (file)
@@ -1,6 +1,6 @@
 /* rltypedefs.h -- Type declarations for readline functions. */
 
-/* Copyright (C) 2000-2021 Free Software Foundation, Inc.
+/* Copyright (C) 2000-2023 Free Software Foundation, Inc.
 
    This file is part of the GNU Readline Library (Readline), a library
    for reading lines of text with interactive input and history editing.      
@@ -28,7 +28,7 @@ extern "C" {
 
 /* Old-style, attempt to mark as deprecated in some way people will notice. */
 
-#if !defined (_FUNCTION_DEF)
+#if !defined (_FUNCTION_DEF) && defined (WANT_OBSOLETE_TYPEDEFS)
 #  define _FUNCTION_DEF
 
 typedef int Function () __attribute__((deprecated));
@@ -36,7 +36,7 @@ typedef void VFunction () __attribute__((deprecated));
 typedef char *CPFunction () __attribute__((deprecated));
 typedef char **CPPFunction () __attribute__((deprecated));
 
-#endif /* _FUNCTION_DEF */
+#endif /* _FUNCTION_DEF && WANT_OBSOLETE_TYPEDEFS */
 
 /* New style. */
 
index ec835e5aa68ebacaa498f942282860e4db949c59..51d746809f3b5e7940dc3f89322663e71ba55af4 100644 (file)
@@ -267,6 +267,9 @@ _rl_handle_signal (int sig)
        sigprocmask (SIG_BLOCK, &set, &oset);
 #endif
 
+#if defined (READLINE_CALLBACKS)
+      if (RL_ISSTATE (RL_STATE_CALLBACK) == 0 || rl_persistent_signal_handlers)
+#endif
       rl_echo_signal_char (sig);
       rl_cleanup_after_signal ();
 
index f8524e04ac094fe996aa5886a0c7326505b37197..d7c5bbf9cbf00c636044d58164ca2a9a11029041 100644 (file)
@@ -514,10 +514,10 @@ xtrace_print_assignment (char *name, char *value, int assign_list, int xflags)
   /* VALUE should not be NULL when this is called. */
   if (*value == '\0' || assign_list)
     nval = value;
-  else if (sh_contains_shell_metas (value))
-    nval = sh_single_quote (value);
   else if (ansic_shouldquote (value))
     nval = ansic_quote (value, 0, (int *)0);
+  else if (sh_contains_shell_metas (value))
+    nval = sh_single_quote (value);
   else
     nval = value;
 
@@ -554,15 +554,15 @@ xtrace_print_word_list (WORD_LIST *list, int xtflags)
        fprintf (xtrace_fp, "''%s", w->next ? " " : "");
       else if (xtflags & 2)
        fprintf (xtrace_fp, "%s%s", t, w->next ? " " : "");
-      else if (sh_contains_shell_metas (t))
+      else if (ansic_shouldquote (t))
        {
-         x = sh_single_quote (t);
+         x = ansic_quote (t, 0, (int *)0);
          fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
          free (x);
        }
-      else if (ansic_shouldquote (t))
+      else if (sh_contains_shell_metas (t))
        {
-         x = ansic_quote (t, 0, (int *)0);
+         x = sh_single_quote (t);
          fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
          free (x);
        }