about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <p.w.stephenson@ntlworld.com>2014-12-07 19:18:23 +0000
committerPeter Stephenson <p.w.stephenson@ntlworld.com>2014-12-07 19:18:23 +0000
commit20f694d101ae72d2ffecc28abe90144ffeeb27e4 (patch)
treedff415f4785c1a963cc6245720e27db39db8317c
parentd90554e46932c73e24aa9748161d069468ad0713 (diff)
downloadzsh-20f694d101ae72d2ffecc28abe90144ffeeb27e4.tar.gz
zsh-20f694d101ae72d2ffecc28abe90144ffeeb27e4.tar.xz
zsh-20f694d101ae72d2ffecc28abe90144ffeeb27e4.zip
33911: 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.
-rw-r--r--Src/loop.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/Src/loop.c b/Src/loop.c
index 69805ea9e..9b0a8d79c 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -643,7 +643,7 @@ exectry(Estate state, int do_exec)
 {
     Wordcode end, always;
     int endval;
-    int save_retflag, save_breaks, save_contflag;
+    int save_retflag, save_breaks, save_contflag, try_interrupt;
     zlong save_try_errflag, save_try_tryflag;
 
     end = state->pc + WC_TRY_SKIP(state->pc[-1]);
@@ -671,8 +671,10 @@ exectry(Estate state, int do_exec)
 
     /* The always clause. */
     save_try_errflag = try_errflag;
-    try_errflag = (zlong)errflag;
-    errflag &= ~ERRFLAG_ERROR;
+    try_errflag = (zlong)(errflag & ERRFLAG_ERROR);
+    try_interrupt = errflag & ERRFLAG_INT;
+    /* We need to reset all errors to allow the block to execute */
+    errflag = 0;
     save_retflag = retflag;
     retflag = 0;
     save_breaks = breaks;
@@ -687,6 +689,17 @@ exectry(Estate state, int do_exec)
 	errflag |= ERRFLAG_ERROR;
     else
 	errflag &= ~ERRFLAG_ERROR;
+    /*
+     * TODO: currently, we always restore the interrupt
+     * error status.  We should have a way of clearing it.
+     * Doing this with try_errflag (the shell variable TRY_BLOCK_ERROR)
+     * is probably not a good idea since currently that's documented
+     * such that setting it to 0 clears errors, and we don't want
+     * to clear interrupts as a side effect.  So it probably needs
+     * a different variable.
+     */
+    if (try_interrupt)
+	errflag |= ERRFLAG_INT;
     try_errflag = save_try_errflag;
     if (!retflag)
 	retflag = save_retflag;