mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-30 17:09:50 +02:00
fix for rare readline case where read(2) succeeds but also gets a signal as it is returning to user mode; fix for bash completion filename quoting when there is more than one match
This commit is contained in:
@@ -11625,3 +11625,28 @@ lib/readline/isearch.c
|
||||
anything else that would cause signals to be processed.
|
||||
Report and fix from Grisha Levit <grishalevit@gmail.com> based on
|
||||
a report from penguin p <tgckpg@gmail.com>
|
||||
|
||||
8/21
|
||||
----
|
||||
lib/readline/input.c
|
||||
- rl_getc: it is possible, though extremely unlikely, for read(2)
|
||||
to both succeed (result == 1) and receive a signal
|
||||
(_rl_caught_signal != 0).
|
||||
We know we have a signal we're interested in, since readline's
|
||||
handler was called, so we want to handle it immediately and defer
|
||||
returning the character we read until the next time through the loop.
|
||||
From a report from penguin p <tgckpg@gmail.com>
|
||||
- rl_getc: if the application's SIGINT signal handler returns without
|
||||
longjmping or exiting the program, make sure to abort out of
|
||||
searches and numeric arguments, because the readline signal handler
|
||||
has freed necessary state. Previously we did this only for the
|
||||
callback interface
|
||||
|
||||
8/22
|
||||
----
|
||||
bashline.c
|
||||
- bash_quote_filename: only check whether the file exists and change
|
||||
the quote character accordingly if we have a single match.
|
||||
Otherwise, it's a prefix and likely doesn't exist, so we'll stick
|
||||
with the default backslash completion quoting style.
|
||||
Fixes completion quoting issue from Aaron Laws <dartme18@gmail.com>
|
||||
|
||||
+3
-1
@@ -4415,9 +4415,11 @@ bash_quote_filename (char *s, int rtype, char *qcp)
|
||||
quoted correctly using backslashes (a backslash-newline pair is
|
||||
special to the shell parser). */
|
||||
expchar = nextch = closer = 0;
|
||||
/* Only check whether the file exists if we're quoting a single completion.
|
||||
Otherwise, it's a common prefix and probably doesn't exist. */
|
||||
if (*qcp == '\0' && cs == COMPLETE_BSQUOTE && dircomplete_expand == 0 &&
|
||||
(expchar = bash_check_expchar (s, 0, &nextch, &closer)) &&
|
||||
file_exists (s) == 0)
|
||||
rtype == SINGLE_MATCH && file_exists (s) == 0)
|
||||
{
|
||||
/* If it looks like the name is subject to expansion, see if we want to
|
||||
double-quote it. */
|
||||
|
||||
+35
-7
@@ -825,8 +825,14 @@ rl_read_key (void)
|
||||
{
|
||||
if (rl_get_char (&c) == 0)
|
||||
c = (*rl_getc_function) (rl_instream);
|
||||
/* fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: _rl_caught_signal = %d\r\n", _rl_caught_signal); */
|
||||
if (_rl_caught_signal)
|
||||
{
|
||||
fprintf(stderr, "rl_read_key: calling RL_CHECK_SIGNALS: c = %d _rl_caught_signal = %d\r\n", c, _rl_caught_signal);
|
||||
if (c > 0)
|
||||
rl_stuff_char (c);
|
||||
c = -1;
|
||||
RL_CHECK_SIGNALS ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -837,13 +843,14 @@ int
|
||||
rl_getc (FILE *stream)
|
||||
{
|
||||
int result, ostate, osig;
|
||||
unsigned char c;
|
||||
unsigned char c, savec;
|
||||
int fd;
|
||||
#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
|
||||
sigset_t empty_set;
|
||||
fd_set readfds;
|
||||
#endif
|
||||
|
||||
savec = 0;
|
||||
fd = fileno (stream);
|
||||
while (1)
|
||||
{
|
||||
@@ -859,12 +866,19 @@ rl_getc (FILE *stream)
|
||||
chance to react or abort some current operation that gets cleaned
|
||||
up by rl_callback_sigcleanup(). If not, we'll just run through the
|
||||
loop again. */
|
||||
if (osig != 0 && (ostate & RL_STATE_CALLBACK))
|
||||
if (osig != 0 && (ostate & RL_STATE_CALLBACK)) /* XXX - when not in callback mode also? */
|
||||
goto postproc_signal;
|
||||
#endif
|
||||
|
||||
/* We know at this point that _rl_caught_signal == 0 */
|
||||
|
||||
if (savec > 0)
|
||||
{
|
||||
c = savec;
|
||||
savec = 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
#if defined (__MINGW32__)
|
||||
if (isatty (fd))
|
||||
return (_getch ()); /* "There is no error return." */
|
||||
@@ -888,6 +902,20 @@ rl_getc (FILE *stream)
|
||||
if (result >= 0)
|
||||
result = read (fd, &c, sizeof (unsigned char));
|
||||
|
||||
/* fprintf(stderr, "rl_getc: read result = %d errno = %d _rl_caught_signal = %d\n", result, errno, _rl_caught_signal); */
|
||||
/* It is possible, though extremely unlikely, for read to both succeed
|
||||
(result == 1) and receive a signal (_rl_caught_signal != 0). We
|
||||
know we have a signal we're interested in, since readline's handler
|
||||
was called, so we want to handle it below and defer returning the
|
||||
character we read until the next time through the loop. */
|
||||
if (result > 0 && _rl_caught_signal != 0)
|
||||
{
|
||||
if (c > 0) /* if result == 1 we assume that c is valid */
|
||||
savec = c; /* one level of pushback */
|
||||
result = -1;
|
||||
errno = EINTR;
|
||||
}
|
||||
|
||||
if (result == sizeof (unsigned char))
|
||||
return (c);
|
||||
|
||||
@@ -923,7 +951,7 @@ rl_getc (FILE *stream)
|
||||
#undef X_EWOULDBLOCK
|
||||
#undef X_EAGAIN
|
||||
|
||||
/* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */
|
||||
/* fprintf(stderr, "rl_getc: read result = %d errno = %d _rl_caught_signal = %d\n", result, errno, _rl_caught_signal); */
|
||||
|
||||
/* Handle errors here. */
|
||||
osig = _rl_caught_signal;
|
||||
@@ -975,11 +1003,11 @@ postproc_signal:
|
||||
call the application's signal event hook. */
|
||||
if (rl_signal_event_hook)
|
||||
(*rl_signal_event_hook) ();
|
||||
#if defined (READLINE_CALLBACKS)
|
||||
else if (osig == SIGINT && (ostate & RL_STATE_CALLBACK) && (ostate & (RL_STATE_ISEARCH|RL_STATE_NSEARCH|RL_STATE_NUMERICARG)))
|
||||
/* If the application's SIGINT handler returns, make sure we abort out of
|
||||
searches and numeric arguments because we've freed necessary state. */
|
||||
if (osig == SIGINT && (ostate & (RL_STATE_ISEARCH|RL_STATE_NSEARCH|RL_STATE_NUMERICARG)))
|
||||
/* just these cases for now */
|
||||
_rl_abort_internal ();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# shell functions to include in multiple test files
|
||||
|
||||
# squeeze out blanks to avoid white space differences in od implementations
|
||||
_intl_normalize_spaces()
|
||||
{
|
||||
sed -e 's/[[:space:]]\{1,\}/ /g' -e 's/[[:space:]]*$//'
|
||||
}
|
||||
|
||||
# avoid whitespace differences in wc implementations
|
||||
_cut_leading_spaces()
|
||||
{
|
||||
sed -e 's/^[ ]*//g'
|
||||
}
|
||||
Reference in New Issue
Block a user