ash: [BUILTIN] Exit without arguments in a trap should use status outside traps
Upstream commit: Date: Mon Oct 6 10:39:47 2014 +0800 [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> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
f7eea8c235
commit
4ccddc8fb3
43
shell/ash.c
43
shell/ash.c
@ -384,6 +384,7 @@ struct globals_misc {
|
|||||||
uint8_t exitstatus; /* exit status of last command */
|
uint8_t exitstatus; /* exit status of last command */
|
||||||
uint8_t back_exitstatus;/* exit status of backquoted command */
|
uint8_t back_exitstatus;/* exit status of backquoted command */
|
||||||
smallint job_warning; /* user was warned about stopped jobs (can be 2, 1 or 0). */
|
smallint job_warning; /* user was warned about stopped jobs (can be 2, 1 or 0). */
|
||||||
|
int savestatus; /* exit status of last command outside traps */
|
||||||
int rootpid; /* pid of main shell */
|
int rootpid; /* pid of main shell */
|
||||||
/* shell level: 0 for the main shell, 1 for its children, and so on */
|
/* shell level: 0 for the main shell, 1 for its children, and so on */
|
||||||
int shlvl;
|
int shlvl;
|
||||||
@ -466,6 +467,7 @@ extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc;
|
|||||||
#define exitstatus (G_misc.exitstatus )
|
#define exitstatus (G_misc.exitstatus )
|
||||||
#define back_exitstatus (G_misc.back_exitstatus )
|
#define back_exitstatus (G_misc.back_exitstatus )
|
||||||
#define job_warning (G_misc.job_warning)
|
#define job_warning (G_misc.job_warning)
|
||||||
|
#define savestatus (G_misc.savestatus )
|
||||||
#define rootpid (G_misc.rootpid )
|
#define rootpid (G_misc.rootpid )
|
||||||
#define shlvl (G_misc.shlvl )
|
#define shlvl (G_misc.shlvl )
|
||||||
#define errlinno (G_misc.errlinno )
|
#define errlinno (G_misc.errlinno )
|
||||||
@ -491,6 +493,7 @@ extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc;
|
|||||||
#define INIT_G_misc() do { \
|
#define INIT_G_misc() do { \
|
||||||
(*(struct globals_misc**)not_const_pp(&ash_ptr_to_globals_misc)) = xzalloc(sizeof(G_misc)); \
|
(*(struct globals_misc**)not_const_pp(&ash_ptr_to_globals_misc)) = xzalloc(sizeof(G_misc)); \
|
||||||
barrier(); \
|
barrier(); \
|
||||||
|
savestatus = -1; \
|
||||||
curdir = nullstr; \
|
curdir = nullstr; \
|
||||||
physdir = nullstr; \
|
physdir = nullstr; \
|
||||||
trap_ptr = trap; \
|
trap_ptr = trap; \
|
||||||
@ -9055,12 +9058,17 @@ dotrap(void)
|
|||||||
{
|
{
|
||||||
uint8_t *g;
|
uint8_t *g;
|
||||||
int sig;
|
int sig;
|
||||||
uint8_t last_status;
|
int status, last_status;
|
||||||
|
|
||||||
if (!pending_sig)
|
if (!pending_sig)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
last_status = exitstatus;
|
status = savestatus;
|
||||||
|
last_status = status;
|
||||||
|
if (status < 0) {
|
||||||
|
status = exitstatus;
|
||||||
|
savestatus = status;
|
||||||
|
}
|
||||||
pending_sig = 0;
|
pending_sig = 0;
|
||||||
barrier();
|
barrier();
|
||||||
|
|
||||||
@ -9087,8 +9095,10 @@ dotrap(void)
|
|||||||
if (!p)
|
if (!p)
|
||||||
continue;
|
continue;
|
||||||
evalstring(p, 0);
|
evalstring(p, 0);
|
||||||
|
exitstatus = status;
|
||||||
}
|
}
|
||||||
exitstatus = last_status;
|
|
||||||
|
savestatus = last_status;
|
||||||
TRACE(("dotrap returns\n"));
|
TRACE(("dotrap returns\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13416,8 +13426,15 @@ exitcmd(int argc UNUSED_PARAM, char **argv)
|
|||||||
{
|
{
|
||||||
if (stoppedjobs())
|
if (stoppedjobs())
|
||||||
return 0;
|
return 0;
|
||||||
if (argv[1])
|
|
||||||
exitstatus = number(argv[1]);
|
if (argv[1]) {
|
||||||
|
int status = number(argv[1]);
|
||||||
|
|
||||||
|
exitstatus = status;
|
||||||
|
if (savestatus >= 0)
|
||||||
|
savestatus = status;
|
||||||
|
}
|
||||||
|
|
||||||
raise_exception(EXEXIT);
|
raise_exception(EXEXIT);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
@ -14077,19 +14094,15 @@ exitshell(void)
|
|||||||
{
|
{
|
||||||
struct jmploc loc;
|
struct jmploc loc;
|
||||||
char *p;
|
char *p;
|
||||||
int status;
|
|
||||||
|
|
||||||
#if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
|
#if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
|
||||||
if (line_input_state)
|
if (line_input_state)
|
||||||
save_history(line_input_state);
|
save_history(line_input_state);
|
||||||
#endif
|
#endif
|
||||||
status = exitstatus;
|
savestatus = exitstatus;
|
||||||
TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
|
TRACE(("pid %d, exitshell(%d)\n", getpid(), savestatus));
|
||||||
if (setjmp(loc.loc)) {
|
if (setjmp(loc.loc))
|
||||||
if (exception_type == EXEXIT)
|
|
||||||
status = exitstatus;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
exception_handler = &loc;
|
exception_handler = &loc;
|
||||||
p = trap[0];
|
p = trap[0];
|
||||||
if (p) {
|
if (p) {
|
||||||
@ -14104,7 +14117,7 @@ exitshell(void)
|
|||||||
*/
|
*/
|
||||||
setjobctl(0);
|
setjobctl(0);
|
||||||
flush_stdout_stderr();
|
flush_stdout_stderr();
|
||||||
_exit(status);
|
_exit(savestatus);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14280,6 +14293,10 @@ reset(void)
|
|||||||
/* from eval.c: */
|
/* from eval.c: */
|
||||||
evalskip = 0;
|
evalskip = 0;
|
||||||
loopnest = 0;
|
loopnest = 0;
|
||||||
|
if (savestatus >= 0) {
|
||||||
|
exitstatus = savestatus;
|
||||||
|
savestatus = -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* from expand.c: */
|
/* from expand.c: */
|
||||||
ifsfree();
|
ifsfree();
|
||||||
|
2
shell/ash_test/ash-misc/exitcode_trap1.right
Normal file
2
shell/ash_test/ash-misc/exitcode_trap1.right
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Trapped
|
||||||
|
One:1
|
6
shell/ash_test/ash-misc/exitcode_trap1.tests
Executable file
6
shell/ash_test/ash-misc/exitcode_trap1.tests
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
# "exit" in trap should not use last command's exitcode,
|
||||||
|
# but exitcode on entering the trap.
|
||||||
|
(trap "echo Trapped; exit" EXIT
|
||||||
|
(exit 1)
|
||||||
|
)
|
||||||
|
echo One:$?
|
Loading…
Reference in New Issue
Block a user