fix for exit builtin when ignoreeof set; better resource deallocation when completion is interrupted; fix small memleak in globbing; compile out obsolete readline typedefs by default; readline callback mode doesn't print signal chars by default; xtrace mode prefers to use $'...' quoting if required

This commit is contained in:
Chet Ramey
2023-06-26 17:09:08 -04:00
parent 81f7b44564
commit 829aad36db
8 changed files with 133 additions and 41 deletions
+7
View 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);
}
+61 -29
View 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. */
+3 -3
View 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. */
+3
View 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 ();