aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2018-12-14 13:52:02 +0800
committerBen Hutchings <ben@decadent.org.uk>2020-03-28 21:42:55 +0000
commit0d63aab8d433cd244e221aee978d2bcd4153cd1a (patch)
tree60b8b40e2edd3dbfe44a41dc02a3523493c2c222
parent2993257551260450b6471d0650bec6e859cafed4 (diff)
downloadklibc-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.h3
-rw-r--r--usr/dash/eval.c9
-rw-r--r--usr/dash/exec.c2
-rw-r--r--usr/dash/main.c2
-rw-r--r--usr/dash/trap.c5
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 */
}