about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBart Schaefer <barts@users.sourceforge.net>2005-12-15 04:24:04 +0000
committerBart Schaefer <barts@users.sourceforge.net>2005-12-15 04:24:04 +0000
commit174ad4a80fa13a843a319c516e703ae74858ad39 (patch)
tree1423c7b97cf838be9f0d8af3913475d4914c700d
parentc3e8aec7592bc9957c86a8be7883fdb6ae738095 (diff)
downloadzsh-174ad4a80fa13a843a319c516e703ae74858ad39.tar.gz
zsh-174ad4a80fa13a843a319c516e703ae74858ad39.tar.xz
zsh-174ad4a80fa13a843a319c516e703ae74858ad39.zip
21814: error handling for traps in "always" constructs.
-rw-r--r--ChangeLog8
-rw-r--r--Src/loop.c11
-rw-r--r--Src/signals.c9
3 files changed, 25 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 7a29b908c..1e8cd1e33 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2005-12-14  Bart Schaefer  <schaefer@zsh.org>
+
+	* 21814: Src/loop.c, Src/signals.c: if an error occurs in an
+	inline trap, set $? to 1, to match the behavior of pre-4.2
+	versions of zsh.  If and only if the trap is executed within the
+	"try" part of an "always" construct, also propagate the error
+	condition so that the "try" section is aborted.  (Belated commit.)
+
 2005-12-14  Wayne Davison  <wayned@users.sourceforge.net>
 
 	* 22078: Src/utils.c: made ucs4toutf8() a static function (when
diff --git a/Src/loop.c b/Src/loop.c
index 56c76b4bb..a29ac1982 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -627,13 +627,17 @@ zlong
 try_errflag = -1;
 
 /**/
+zlong
+try_tryflag = 0;
+
+/**/
 int
 exectry(Estate state, int do_exec)
 {
     Wordcode end, always;
     int endval;
     int save_retflag, save_breaks, save_loops, save_contflag;
-    zlong save_try_errflag;
+    zlong save_try_errflag, save_try_tryflag;
 
     end = state->pc + WC_TRY_SKIP(state->pc[-1]);
     always = state->pc + 1 + WC_TRY_SKIP(*state->pc);
@@ -642,8 +646,13 @@ exectry(Estate state, int do_exec)
     cmdpush(CS_CURSH);
 
     /* The :try clause */
+    save_try_tryflag = try_tryflag;
+    try_tryflag = 1;
+
     execlist(state, 1, do_exec);
 
+    try_tryflag = save_try_tryflag;
+
     /* Don't record errflag here, may be reset. */
     endval = lastval;
 
diff --git a/Src/signals.c b/Src/signals.c
index e9571ef5b..0b508f869 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -1003,6 +1003,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
     int trapret = 0;
     int obreaks = breaks;
     int isfunc;
+    int traperr;
 
     /* if signal is being ignored or the trap function		      *
      * is NULL, then return					      *
@@ -1097,8 +1098,8 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
 	 * execrestore.
 	 */
 	trapret = trapreturn + 1;
-    } else if (errflag)
-	trapret = 1;
+    }
+    traperr = errflag;
     execrestore();
     lexrestore();
 
@@ -1110,6 +1111,10 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
 	    lastval = trapret-1;
 	}
     } else {
+	if (traperr && emulation != EMULATE_SH)
+	    lastval = 1;
+	if (try_tryflag)
+	    errflag = traperr;
 	breaks += obreaks;
 	if (breaks > loops)
 	    breaks = loops;