diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2014-10-06 10:39:47 +0800 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2014-10-06 10:39:47 +0800 |
commit | da30b4b787695fbf77e5d941ff350a66ca572bcb (patch) | |
tree | 42950a7661b842fe4279bf5c28684def3c8c8fd8 /src/trap.c | |
parent | [EVAL] Do not clobber exitstatus in evalcommand (diff) | |
download | dash-da30b4b787695fbf77e5d941ff350a66ca572bcb.tar.gz dash-da30b4b787695fbf77e5d941ff350a66ca572bcb.zip |
[BUILTIN] Exit without arguments in a trap should use status outside traps
POSIX now requires that exit without arguments in a trap should return the last command status prior to executing traps. This patch implements this behaviour. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'src/trap.c')
-rw-r--r-- | src/trap.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/src/trap.c b/src/trap.c index e34e0f8..15faeff 100644 --- a/src/trap.c +++ b/src/trap.c @@ -314,12 +314,17 @@ void dotrap(void) char *p; char *q; int i; - int savestatus; + int status, last_status; if (!pendingsigs) return; - savestatus = exitstatus; + status = savestatus; + last_status = status; + if (likely(status < 0)) { + status = exitstatus; + savestatus = status; + } pendingsigs = 0; barrier(); @@ -338,8 +343,10 @@ void dotrap(void) if (!p) continue; evalstring(p, 0); - exitstatus = savestatus; + exitstatus = status; } + + savestatus = last_status; } @@ -373,18 +380,14 @@ exitshell(void) { struct jmploc loc; char *p; - volatile int status; #ifdef HETIO hetio_reset_term(); #endif - status = exitstatus; - TRACE(("pid %d, exitshell(%d)\n", getpid(), status)); - if (setjmp(loc.loc)) { - if (exception == EXEXIT) - status = exitstatus; + savestatus = exitstatus; + TRACE(("pid %d, exitshell(%d)\n", getpid(), savestatus)); + if (setjmp(loc.loc)) goto out; - } handler = &loc; if ((p = trap[0])) { trap[0] = NULL; @@ -399,7 +402,7 @@ out: if (likely(!setjmp(loc.loc))) setjobctl(0); flushall(); - _exit(status); + _exit(savestatus); /* NOTREACHED */ } |