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>
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;
#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
{ "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
#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
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;
if (free_dirname)
free (directory_name);
+
return (result);
}
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 */
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
{
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);
if (matches && matches[0] && *matches[0])
last_completion_failed = 0;
+ do_display = 0;
+
switch (what_to_do)
{
case TAB:
{
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)
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:
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. */
/* 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.
/* 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));
typedef char *CPFunction () __attribute__((deprecated));
typedef char **CPPFunction () __attribute__((deprecated));
-#endif /* _FUNCTION_DEF */
+#endif /* _FUNCTION_DEF && WANT_OBSOLETE_TYPEDEFS */
/* New style. */
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 ();
/* 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;
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);
}