From 9958684574bf8b0ecec6983cca57f3fa3dd7cd63 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Sun, 9 Aug 2015 00:50:36 -0700 Subject: 36022 fix bug that some loop constructs could not be interrupted, revise signal queueing There are two underlying ideas here: (1) Keeping signals queued around anything that's doing memory management (including push/pop of the heap) has become crucial. (2) Anytime the shell is going to run a command, be it buitin or external, it must be both safe and necessary to process any queued signals, so that the apparent order of signal arrival and command execution is preserved. --- Src/input.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'Src/input.c') diff --git a/Src/input.c b/Src/input.c index 1efabadeb..eb968ea72 100644 --- a/Src/input.c +++ b/Src/input.c @@ -141,16 +141,19 @@ shingetline(void) int c; char buf[BUFSIZ]; char *p; + int q = queue_signal_level(); p = buf; - winch_unblock(); for (;;) { + winch_unblock(); + dont_queue_signals(); do { errno = 0; c = fgetc(bshin); } while (c < 0 && errno == EINTR); if (c < 0 || c == '\n') { winch_block(); + restore_queue_signals(q); if (c == '\n') *p++ = '\n'; if (p > buf) { @@ -167,12 +170,13 @@ shingetline(void) *p++ = c; if (p >= buf + BUFSIZ - 1) { winch_block(); + queue_signals(); line = zrealloc(line, ll + (p - buf) + 1); memcpy(line + ll, buf, p - buf); ll += p - buf; line[ll] = '\0'; p = buf; - winch_unblock(); + unqueue_signals(); } } } @@ -377,6 +381,8 @@ inputline(void) static void inputsetline(char *str, int flags) { + queue_signals(); + if ((inbufflags & INP_FREE) && inbuf) { free(inbuf); } @@ -394,6 +400,8 @@ inputsetline(char *str, int flags) else inbufct = inbufleft; inbufflags = flags; + + unqueue_signals(); } /* -- cgit 1.4.1