about summary refs log tree commit diff
path: root/Src/loop.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/loop.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/loop.c')
-rw-r--r--Src/loop.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/Src/loop.c b/Src/loop.c
index 82d2fe31a..8bb1ec9dd 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -259,7 +259,8 @@ execselect(Estate state, UNUSED(int do_exec))
 				   0, ZLCON_SELECT);
 		    if (errflag)
 			str = NULL;
-		    errflag = oef;
+		    /* Keep any user interrupt error status */
+		    errflag = oef | (errflag & ERRFLAG_INT);
 	    	} else {
 		    str = promptexpand(prompt3, 0, NULL, NULL, NULL);
 		    zputs(str, stderr);
@@ -632,6 +633,14 @@ execcase(Estate state, int do_exec)
 zlong
 try_errflag = -1;
 
+/**
+ * Corresponding interrupt error status form `try' block.
+ */
+
+/**/
+zlong
+try_interrupt = -1;
+
 /**/
 zlong
 try_tryflag = 0;
@@ -643,7 +652,7 @@ exectry(Estate state, int do_exec)
     Wordcode end, always;
     int endval;
     int save_retflag, save_breaks, save_contflag;
-    zlong save_try_errflag, save_try_tryflag;
+    zlong save_try_errflag, save_try_tryflag, save_try_interrupt;
 
     end = state->pc + WC_TRY_SKIP(state->pc[-1]);
     always = state->pc + 1 + WC_TRY_SKIP(*state->pc);
@@ -670,7 +679,10 @@ exectry(Estate state, int do_exec)
 
     /* The always clause. */
     save_try_errflag = try_errflag;
-    try_errflag = (zlong)errflag;
+    save_try_interrupt = try_interrupt;
+    try_errflag = (zlong)(errflag & ERRFLAG_ERROR);
+    try_interrupt = (zlong)((errflag & ERRFLAG_INT) ? 1 : 0);
+    /* We need to reset all errors to allow the block to execute */
     errflag = 0;
     save_retflag = retflag;
     retflag = 0;
@@ -682,8 +694,16 @@ exectry(Estate state, int do_exec)
     state->pc = always;
     execlist(state, 1, do_exec);
 
-    errflag = try_errflag ? 1 : 0;
+    if (try_errflag)
+	errflag |= ERRFLAG_ERROR;
+    else
+	errflag &= ~ERRFLAG_ERROR;
+    if (try_interrupt)
+	errflag |= ERRFLAG_INT;
+    else
+	errflag &= ~ERRFLAG_INT;
     try_errflag = save_try_errflag;
+    try_interrupt = save_try_interrupt;
     if (!retflag)
 	retflag = save_retflag;
     if (!breaks)