diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2018-12-14 13:52:02 +0800 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2020-03-28 21:42:55 +0000 |
commit | 0d63aab8d433cd244e221aee978d2bcd4153cd1a (patch) | |
tree | 60b8b40e2edd3dbfe44a41dc02a3523493c2c222 | |
parent | 2993257551260450b6471d0650bec6e859cafed4 (diff) | |
download | klibc-0d63aab8d433cd244e221aee978d2bcd4153cd1a.tar.gz |
[klibc] dash: eval: Only restore exit status on exit/return
[ dash commit 62cf6955f8abe875752d7163f6f3adbc7e49ebae ]
We unconditionally restore the saved status in exitreset, which
is incorrect as we only want to do it for exitcmd and returncmd.
This patch fixes the problem by introducing EXEND.
Reported-by: Martijn Dekker <martijn@inlv.org>
Fixes: da30b4b78769 ("[BUILTIN] Exit without arguments in a trap...")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r-- | usr/dash/error.h | 3 | ||||
-rw-r--r-- | usr/dash/eval.c | 9 | ||||
-rw-r--r-- | usr/dash/exec.c | 2 | ||||
-rw-r--r-- | usr/dash/main.c | 2 | ||||
-rw-r--r-- | usr/dash/trap.c | 5 |
5 files changed, 13 insertions, 8 deletions
diff --git a/usr/dash/error.h b/usr/dash/error.h index f91d11d14fd35..8df0134f8b865 100644 --- a/usr/dash/error.h +++ b/usr/dash/error.h @@ -69,7 +69,8 @@ extern int exception; /* exceptions */ #define EXINT 0 /* SIGINT received */ #define EXERROR 1 /* a generic error */ -#define EXEXIT 4 /* exit the shell */ +#define EXEND 3 /* exit the shell */ +#define EXEXIT 4 /* exit the shell via exitcmd */ /* diff --git a/usr/dash/eval.c b/usr/dash/eval.c index bba0e7f88ea4b..1aad31a0ff97a 100644 --- a/usr/dash/eval.c +++ b/usr/dash/eval.c @@ -114,12 +114,13 @@ STATIC const struct builtincmd bltin = { INCLUDE "eval.h" EXITRESET { - evalskip = 0; - loopnest = 0; if (savestatus >= 0) { - exitstatus = savestatus; + if (exception == EXEXIT || evalskip == SKIPFUNCDEF) + exitstatus = savestatus; savestatus = -1; } + evalskip = 0; + loopnest = 0; } #endif @@ -318,7 +319,7 @@ out: if (flags & EV_EXIT) { exexit: - exraise(EXEXIT); + exraise(EXEND); } popstackmark(&smark); diff --git a/usr/dash/exec.c b/usr/dash/exec.c index 9d0215a6533f3..87354d495aaf2 100644 --- a/usr/dash/exec.c +++ b/usr/dash/exec.c @@ -143,7 +143,7 @@ shellexec(char **argv, const char *path, int idx) exitstatus = exerrno; TRACE(("shellexec failed for %s, errno %d, suppressint %d\n", argv[0], e, suppressint )); - exerror(EXEXIT, "%s: %s", argv[0], errmsg(e, E_EXEC)); + exerror(EXEND, "%s: %s", argv[0], errmsg(e, E_EXEC)); /* NOTREACHED */ } diff --git a/usr/dash/main.c b/usr/dash/main.c index 6d53e0090d921..6b3a0909f51d6 100644 --- a/usr/dash/main.c +++ b/usr/dash/main.c @@ -111,7 +111,7 @@ main(int argc, char **argv) e = exception; s = state; - if (e == EXEXIT || s == 0 || iflag == 0 || shlvl) + if (e == EXEND || e == EXEXIT || s == 0 || iflag == 0 || shlvl) exitshell(); reset(); diff --git a/usr/dash/trap.c b/usr/dash/trap.c index 1ad27e99ff460..838008d22b314 100644 --- a/usr/dash/trap.c +++ b/usr/dash/trap.c @@ -42,6 +42,7 @@ #include "main.h" #include "nodes.h" /* for other headers */ #include "eval.h" +#include "init.h" #include "jobs.h" #include "show.h" #include "options.h" @@ -396,8 +397,10 @@ exitshell(void) trap[0] = NULL; evalskip = 0; evalstring(p, 0); + evalskip = SKIPFUNCDEF; } out: + exitreset(); /* * Disable job control so that whoever had the foreground before we * started can get it back. @@ -405,7 +408,7 @@ out: if (likely(!setjmp(loc.loc))) setjobctl(0); flushall(); - _exit(savestatus); + _exit(exitstatus); /* NOTREACHED */ } |