summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChet Ramey <chet.ramey@case.edu>2023-11-17 16:05:13 -0500
committerChet Ramey <chet.ramey@case.edu>2023-11-17 16:05:13 -0500
commit93a6afa50f953246f7c0f93b219a1e4010ba704b (patch)
tree3df5fa672f1943fbbd9add6e6855532dd77e002c
parent37ec317397e442ee8616b3b2aa81bfb8dde71a06 (diff)
Readline-8.2 patch 6: fix for callback signal handling when a signal arrives before readline calls rl_getc and handling it changes callback state
-rw-r--r--input.c28
-rw-r--r--patchlevel2
2 files changed, 28 insertions, 2 deletions
diff --git a/input.c b/input.c
index 68d418c..f68fcac 100644
--- a/input.c
+++ b/input.c
@@ -804,7 +804,7 @@ rl_read_key (void)
int
rl_getc (FILE *stream)
{
- int result;
+ int result, ostate, osig;
unsigned char c;
int fd;
#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
@@ -815,8 +815,22 @@ rl_getc (FILE *stream)
fd = fileno (stream);
while (1)
{
+ osig = _rl_caught_signal;
+ ostate = rl_readline_state;
+
RL_CHECK_SIGNALS ();
+#if defined (READLINE_CALLBACKS)
+ /* Do signal handling post-processing here, but just in callback mode
+ for right now because the signal cleanup can change some of the
+ callback state, and we need to either let the application have a
+ 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))
+ goto postproc_signal;
+#endif
+
/* We know at this point that _rl_caught_signal == 0 */
#if defined (__MINGW32__)
@@ -880,6 +894,9 @@ rl_getc (FILE *stream)
/* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */
handle_error:
+ osig = _rl_caught_signal;
+ ostate = rl_readline_state;
+
/* If the error that we received was EINTR, then try again,
this is simply an interrupted system call to read (). We allow
the read to be interrupted if we caught SIGHUP, SIGTERM, or any
@@ -920,8 +937,17 @@ handle_error:
RL_CHECK_SIGNALS ();
#endif /* SIGALRM */
+postproc_signal:
+ /* POSIX says read(2)/pselect(2)/select(2) don't return EINTR for any
+ reason other than being interrupted by a signal, so we can safely
+ 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)))
+ /* just these cases for now */
+ _rl_abort_internal ();
+#endif
}
}
diff --git a/patchlevel b/patchlevel
index e0ba09d..6ebd6a5 100644
--- a/patchlevel
+++ b/patchlevel
@@ -1,3 +1,3 @@
# Do not edit -- exists only for use by patch
-5
+6