summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Src/signals.c8
-rw-r--r--Test/C03traps.ztst63
3 files changed, 75 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 661ca260d..bd9aeaddb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2007-01-12 Peter Stephenson <p.w.stephenson@ntlworld.com>
+
+ * 23101: Src/signals.c, Test/C03traps.ztst: ZERR traps
+ had various odd features when combined with function returns.
+
2007-01-09 Peter Stephenson <p.w.stephenson@ntlworld.com>
* users/11111: Doc/Zsh/options.yo, Src/exec.c, Src/options.c,
diff --git a/Src/signals.c b/Src/signals.c
index 635a7d341..8478fdd30 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -1071,6 +1071,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
char *name, num[4];
int trapret = 0;
int obreaks = breaks;
+ int oretflag = retflag;
int isfunc;
int traperr;
@@ -1109,7 +1110,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
lexsave();
execsave();
- breaks = 0;
+ breaks = retflag = 0;
runhookdef(BEFORETRAPHOOK, NULL);
if (*sigtr & ZSIG_FUNC) {
int osc = sfcontext;
@@ -1176,15 +1177,20 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
if (isfunc) {
breaks = loops;
errflag = 1;
+ lastval = trapret;
} else {
lastval = trapret-1;
}
+ /* return triggered */
+ retflag = 1;
} else {
if (traperr && emulation != EMULATE_SH)
lastval = 1;
if (try_tryflag)
errflag = traperr;
breaks += obreaks;
+ /* return not triggered: restore old flag */
+ retflag = oretflag;
if (breaks > loops)
breaks = loops;
}
diff --git a/Test/C03traps.ztst b/Test/C03traps.ztst
index 82e401fd1..252ccc4cb 100644
--- a/Test/C03traps.ztst
+++ b/Test/C03traps.ztst
@@ -287,6 +287,69 @@
>child exiting
>wait #2 finished, gotsig=0, status=33
+ fn1() {
+ setopt errexit
+ trap 'echo error1' ZERR
+ false
+ print Shouldn\'t get here 1a
+ }
+ fn2() {
+ setopt errexit
+ trap 'echo error2' ZERR
+ return 1
+ print Shouldn\'t get here 2a
+ }
+ fn3() {
+ setopt errexit
+ TRAPZERR() { echo error3; }
+ false
+ print Shouldn\'t get here 3a
+ }
+ fn4() {
+ setopt errexit
+ TRAPZERR() { echo error4; }
+ return 1
+ print Shouldn\'t get here 4a
+ }
+ (fn1; print Shouldn\'t get here 1b)
+ (fn2; print Shouldn\'t get here 2b)
+ (fn3; print Shouldn\'t get here 3b)
+ (fn4; print Shouldn\'t get here 4b)
+1: Combination of ERR_EXIT and ZERR trap
+>error1
+>error2
+>error3
+>error4
+
+ fn1() { TRAPZERR() { print trap; return 42; }; false; print Broken; }
+ (fn1)
+ print Working $?
+0: Force return of containing function from TRAPZERR.
+>trap
+>Working 42
+
+ fn2() { trap 'print trap; return 42' ZERR; false; print Broken }
+ (fn2)
+ print Working $?
+0: Return with non-zero status triggered from within trap '...' ZERR.
+>trap
+>Working 42
+
+ fn3() { TRAPZERR() { print trap; return 0; }; false; print OK this time; }
+ (fn3)
+ print Working $?
+0: Normal return from TRAPZERR.
+>trap
+>OK this time
+>Working 0
+
+ fn4() { trap 'print trap; return 0' ZERR; false; print Broken; }
+ (fn4)
+ print Working $?
+0: Return with zero status triggered from within trap '...' ZERR.
+>trap
+>Working 0
+
%clean
rm -f TRAPEXIT