mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-23 13:57:58 +02:00
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:
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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. */
|
||||
|
||||
@@ -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. */
|
||||
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
|
||||
+8
-8
@@ -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,18 +554,18 @@ 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))
|
||||
{
|
||||
x = sh_single_quote (t);
|
||||
fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
|
||||
free (x);
|
||||
}
|
||||
else if (ansic_shouldquote (t))
|
||||
{
|
||||
x = ansic_quote (t, 0, (int *)0);
|
||||
fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
|
||||
free (x);
|
||||
}
|
||||
else if (sh_contains_shell_metas (t))
|
||||
{
|
||||
x = sh_single_quote (t);
|
||||
fprintf (xtrace_fp, "%s%s", x, w->next ? " " : "");
|
||||
free (x);
|
||||
}
|
||||
else
|
||||
fprintf (xtrace_fp, "%s%s", t, w->next ? " " : "");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user