about summary refs log tree commit diff
path: root/Src/signals.c
diff options
context:
space:
mode:
authorPeter Stephenson <p.w.stephenson@ntlworld.com>2014-12-07 16:24:19 +0000
committerPeter Stephenson <pws@zsh.org>2014-12-11 09:41:17 +0000
commitd067ebcacd55472f720b2765ec686a69b25c9a90 (patch)
treec22b23a3812456939b9cf284c6ccba1249636443 /Src/signals.c
parent247f7548dc760184dae090834d4a050f4ce32d98 (diff)
downloadzsh-d067ebcacd55472f720b2765ec686a69b25c9a90.tar.gz
zsh-d067ebcacd55472f720b2765ec686a69b25c9a90.tar.xz
zsh-d067ebcacd55472f720b2765ec686a69b25c9a90.zip
33876: etc.: Separate errors and keyboards interrupts
Combination of 12 commits from interrupt_abort branch.

Basic strategy is to introduce bits to errflag and to set and
reset them separately.

Remove interrupt status on return to main keymap.

Turn off ERRFLAG_INT for always block.

Restore bit thereafter: we probably need a new variable in order
to allow user interrupts to be reset in the always block.

Add TRY_BLOCK_INTERRUPT

This works the same as TRY_BLOCK_ERROR, but for a SIGINT, too.

Ensure propagation of SIGINT from exited job.

If received by foreground job, shell uses ERRFLAG_INT, not
ERRFLAG_ERROR, to set the new state.

Reset errflag before precmd()

Add always block in _main_completion to fix ZLS_COLORS

Ensures we get the right state of $ZLS_COLORS at the end of _main_complete
even if there's an interrupt.  However, the "right state" is a bit messy
as it depends on styles.
Diffstat (limited to 'Src/signals.c')
-rw-r--r--Src/signals.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/Src/signals.c b/Src/signals.c
index e72850516..899f1217b 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -619,7 +619,7 @@ zhandler(int sig)
 		zexit(SIGINT, 1);
             if (list_pipe || chline || simple_pline) {
                 breaks = loops;
-                errflag = 1;
+                errflag |= ERRFLAG_INT;
 		inerrflush();
 		check_cursh_sig(SIGINT);
             }
@@ -640,6 +640,11 @@ zhandler(int sig)
 	    if (idle >= 0 && idle < tmout)
 		alarm(tmout - idle);
 	    else {
+		/*
+		 * We want to exit now.
+		 * Cancel all errors, including a user interrupt
+		 * which is now redundant.
+		 */
 		errflag = noerrs = 0;
 		zwarn("timeout");
 		stopmsg = 1;
@@ -1267,7 +1272,18 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
 	!(isfunc && new_trap_return == 0)) {
 	if (isfunc) {
 	    breaks = loops;
-	    errflag = 1;
+	    /*
+	     * For SIGINT we behave the same as the default behaviour
+	     * i.e. we set the error bit indicating an interrupt.
+	     * We do this with SIGQUIT, too, even though we don't
+	     * handle SIGQUIT by default.  That's to try to make
+	     * it behave a bit more like its normal behaviour when
+	     * the trap handler has told us that's what it wants.
+	     */
+	    if (sig == SIGINT || sig == SIGQUIT)
+		errflag |= ERRFLAG_INT;
+	    else
+		errflag |= ERRFLAG_ERROR;
 	}
 	lastval = new_trap_return;
 	/* return triggered */
@@ -1282,8 +1298,12 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
 	     */
 	    lastval = olastval;
 	}
-	if (try_tryflag)
-	    errflag = traperr;
+	if (try_tryflag) {
+	    if (traperr)
+		errflag |= ERRFLAG_ERROR;
+	    else
+		errflag &= ~ERRFLAG_ERROR;
+	}
 	breaks += obreaks;
 	/* return not triggered: restore old flag */
 	retflag = oretflag;