about summary refs log tree commit diff
path: root/Src/init.c
diff options
context:
space:
mode:
authorBarton E. Schaefer <schaefer@zsh.org>2015-08-09 00:50:36 -0700
committerBarton E. Schaefer <schaefer@zsh.org>2015-08-09 16:13:52 -0700
commit9958684574bf8b0ecec6983cca57f3fa3dd7cd63 (patch)
tree81d83526e0bccdb20b3bee421131b7e0b889f361 /Src/init.c
parentce12868837f0140b95ac748f9c35047b4ea4277a (diff)
downloadzsh-9958684574bf8b0ecec6983cca57f3fa3dd7cd63.tar.gz
zsh-9958684574bf8b0ecec6983cca57f3fa3dd7cd63.tar.xz
zsh-9958684574bf8b0ecec6983cca57f3fa3dd7cd63.zip
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.
Diffstat (limited to 'Src/init.c')
-rw-r--r--Src/init.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/Src/init.c b/Src/init.c
index 2ef90992d..f2021f073 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -105,6 +105,7 @@ loop(int toplevel, int justonce)
     Eprog prog;
     int err, non_empty = 0;
 
+    queue_signals();
     pushheap();
     if (!toplevel)
 	zcontext_save();
@@ -126,7 +127,9 @@ loop(int toplevel, int justonce)
 		 * no matter what.
 		 */
 		errflag = 0;
+		unqueue_signals();
 		preprompt();
+		queue_signals();
 		if (stophist != 3)
 		    hbegin(1);
 		else
@@ -218,6 +221,7 @@ loop(int toplevel, int justonce)
 	if (((!interact || sourcelevel) && errflag) || retflag)
 	    break;
 	if (isset(SINGLECOMMAND) && toplevel) {
+	    dont_queue_signals();
 	    if (sigtrapped[SIGEXIT])
 		dotrap(SIGEXIT);
 	    exit(lastval);
@@ -229,6 +233,7 @@ loop(int toplevel, int justonce)
     if (!toplevel)
 	zcontext_restore();
     popheap();
+    unqueue_signals();
 
     if (err)
 	return LOOP_ERROR;