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>
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. */
{
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 ();
+ }
}
}
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)
{
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." */
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);
#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;
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
}
}