diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | Src/signals.c | 8 | ||||
-rw-r--r-- | Test/C03traps.ztst | 63 |
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 |