ash: Return without arguments in a trap should use status outside traps
Fixes exitcode_trap4.tests. Upstream commit: Date: Mon, 6 Oct 2014 21:51:26 +0800 Return without arguments in a trap should use status outside traps POSIX now requires that return without arguments in a trap should return the last command status prior to executing traps. This patch implements this behaviour. Incidentally this also changes the behaviour of return without arguments in a loop conditional to use the last exit status in the body as opposed to the last command in the conditional when there is one. 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
bb095f4838
commit
cd24a50633
23
shell/ash.c
23
shell/ash.c
@ -9091,6 +9091,7 @@ defun(union node *func)
|
|||||||
#define SKIPBREAK (1 << 0)
|
#define SKIPBREAK (1 << 0)
|
||||||
#define SKIPCONT (1 << 1)
|
#define SKIPCONT (1 << 1)
|
||||||
#define SKIPFUNC (1 << 2)
|
#define SKIPFUNC (1 << 2)
|
||||||
|
#define SKIPFUNCDEF (1 << 3)
|
||||||
static smallint evalskip; /* set to SKIPxxx if we are skipping commands */
|
static smallint evalskip; /* set to SKIPxxx if we are skipping commands */
|
||||||
static int skipcount; /* number of levels to skip */
|
static int skipcount; /* number of levels to skip */
|
||||||
static int loopnest; /* current loop nesting level */
|
static int loopnest; /* current loop nesting level */
|
||||||
@ -9148,7 +9149,8 @@ dotrap(void)
|
|||||||
if (!p)
|
if (!p)
|
||||||
continue;
|
continue;
|
||||||
evalstring(p, 0);
|
evalstring(p, 0);
|
||||||
exitstatus = status;
|
if (evalskip != SKIPFUNC)
|
||||||
|
exitstatus = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
savestatus = last_status;
|
savestatus = last_status;
|
||||||
@ -9783,7 +9785,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags)
|
|||||||
shellparam = saveparam;
|
shellparam = saveparam;
|
||||||
exception_handler = savehandler;
|
exception_handler = savehandler;
|
||||||
INT_ON;
|
INT_ON;
|
||||||
evalskip &= ~SKIPFUNC;
|
evalskip &= ~(SKIPFUNC | SKIPFUNCDEF);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9928,12 +9930,23 @@ execcmd(int argc UNUSED_PARAM, char **argv)
|
|||||||
static int FAST_FUNC
|
static int FAST_FUNC
|
||||||
returncmd(int argc UNUSED_PARAM, char **argv)
|
returncmd(int argc UNUSED_PARAM, char **argv)
|
||||||
{
|
{
|
||||||
|
int skip;
|
||||||
|
int status;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If called outside a function, do what ksh does;
|
* If called outside a function, do what ksh does;
|
||||||
* skip the rest of the file.
|
* skip the rest of the file.
|
||||||
*/
|
*/
|
||||||
evalskip = SKIPFUNC;
|
if (argv[1]) {
|
||||||
return argv[1] ? number(argv[1]) : exitstatus;
|
skip = SKIPFUNC;
|
||||||
|
status = number(argv[1]);
|
||||||
|
} else {
|
||||||
|
skip = SKIPFUNCDEF;
|
||||||
|
status = exitstatus;
|
||||||
|
}
|
||||||
|
evalskip = skip;
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Forward declarations for builtintab[] */
|
/* Forward declarations for builtintab[] */
|
||||||
@ -13372,7 +13385,7 @@ cmdloop(int top)
|
|||||||
skip = evalskip;
|
skip = evalskip;
|
||||||
|
|
||||||
if (skip) {
|
if (skip) {
|
||||||
evalskip &= ~SKIPFUNC;
|
evalskip &= ~(SKIPFUNC | SKIPFUNCDEF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user