[klibc] [klibc:update-dash] dash: [BUILTIN] Exit without arguments in a trap should use status outside traps
klibc-bot for Herbert Xu
herbert at gondor.apana.org.au
Sat Mar 28 14:48:20 PDT 2020
Commit-ID: 85a5a4a9d96c0c680597432f1e4454718e7ad101
Gitweb: http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=85a5a4a9d96c0c680597432f1e4454718e7ad101
Author: Herbert Xu <herbert at gondor.apana.org.au>
AuthorDate: Mon, 6 Oct 2014 10:39:47 +0800
Committer: Ben Hutchings <ben at decadent.org.uk>
CommitDate: Sat, 28 Mar 2020 21:42:54 +0000
[klibc] dash: [BUILTIN] Exit without arguments in a trap should use status outside traps
[ dash commit da30b4b787695fbf77e5d941ff350a66ca572bcb ]
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 at gondor.apana.org.au>
Signed-off-by: Ben Hutchings <ben at decadent.org.uk>
---
usr/dash/eval.c | 5 +++++
usr/dash/eval.h | 1 +
usr/dash/main.c | 11 +++++++++--
usr/dash/trap.c | 25 ++++++++++++++-----------
4 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/usr/dash/eval.c b/usr/dash/eval.c
index 3e08e825..1c76d4c5 100644
--- a/usr/dash/eval.c
+++ b/usr/dash/eval.c
@@ -74,6 +74,7 @@ static int funcline; /* starting line number of current function, or 0 if not i
char *commandname;
int exitstatus; /* exit status of last command */
int back_exitstatus; /* exit status of backquoted command */
+int savestatus = -1; /* exit status of last command outside traps */
#if !defined(__alpha__) || (defined(__GNUC__) && __GNUC__ >= 3)
@@ -114,6 +115,10 @@ INCLUDE "eval.h"
RESET {
evalskip = 0;
loopnest = 0;
+ if (savestatus >= 0) {
+ exitstatus = savestatus;
+ savestatus = -1;
+ }
}
#endif
diff --git a/usr/dash/eval.h b/usr/dash/eval.h
index dc8acd2a..6e62137a 100644
--- a/usr/dash/eval.h
+++ b/usr/dash/eval.h
@@ -37,6 +37,7 @@
extern char *commandname; /* currently executing command */
extern int exitstatus; /* exit status of last command */
extern int back_exitstatus; /* exit status of backquoted command */
+extern int savestatus; /* exit status of last command outside traps */
struct backcmd { /* result of evalbackcmd */
diff --git a/usr/dash/main.c b/usr/dash/main.c
index f79ad7dd..29a258d3 100644
--- a/usr/dash/main.c
+++ b/usr/dash/main.c
@@ -339,8 +339,15 @@ exitcmd(int argc, char **argv)
{
if (stoppedjobs())
return 0;
- if (argc > 1)
- exitstatus = number(argv[1]);
+
+ if (argc > 1) {
+ int status = number(argv[1]);
+
+ exitstatus = status;
+ if (savestatus >= 0)
+ savestatus = status;
+ }
+
exraise(EXEXIT);
/* NOTREACHED */
}
diff --git a/usr/dash/trap.c b/usr/dash/trap.c
index 3ff45318..7dd8342f 100644
--- a/usr/dash/trap.c
+++ b/usr/dash/trap.c
@@ -313,12 +313,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();
@@ -337,8 +342,10 @@ void dotrap(void)
if (!p)
continue;
evalstring(p, 0);
- exitstatus = savestatus;
+ exitstatus = status;
}
+
+ savestatus = last_status;
}
@@ -372,18 +379,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;
@@ -398,7 +401,7 @@ out:
if (likely(!setjmp(loc.loc)))
setjobctl(0);
flushall();
- _exit(status);
+ _exit(savestatus);
/* NOTREACHED */
}
More information about the klibc
mailing list