diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/exec.c | 18 | ||||
-rw-r--r-- | Src/init.c | 2 | ||||
-rw-r--r-- | Src/signals.c | 2 |
3 files changed, 20 insertions, 2 deletions
diff --git a/Src/exec.c b/Src/exec.c index 8edbf1dc9..daa7ba55c 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -64,7 +64,23 @@ int nohistsave; /**/ mod_export int errflag; -/* Status of return from a trap */ +/* + * Status of return from a trap. + * This is only active if we are inside a trap, else its value + * is irrelevant. It is initialised to -1 for a function trap and + * -2 for a non-function trap and if negative is decremented as + * we go deeper into functions and incremented as we come back up. + * The value is used to decide if an explicit "return" should cause + * a return from the caller of the trap; it does this by setting + * trapreturn to a status (i.e. a non-negative value). + * + * In summary, trapreturn is + * - zero unless we are in a trap + * - negative in a trap unless it has triggered. Code uses this + * to detect an active trap. + * - non-negative in a trap once it was triggered. It should remain + * non-negative until restored after execution of the trap. + */ /**/ int trapreturn; diff --git a/Src/init.c b/Src/init.c index cf6164321..fcbf9236c 100644 --- a/Src/init.c +++ b/Src/init.c @@ -191,7 +191,7 @@ loop(int toplevel, int justonce) exit(lastval); if (((!interact || sourcelevel) && errflag) || retflag) break; - if (trapreturn) { + if (trapreturn >= 0) { lastval = trapreturn; trapreturn = 0; } diff --git a/Src/signals.c b/Src/signals.c index 022ee8fb5..61fff64a2 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -1085,6 +1085,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn) int trapret = 0; int obreaks = breaks; int oretflag = retflag; + int otrapreturn = trapreturn; int isfunc; int traperr; @@ -1183,6 +1184,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn) trapret = trapreturn + 1; } traperr = errflag; + trapreturn = otrapreturn; execrestore(); lexrestore(); |