ash: eval: Do not cache value of eflag in evaltree
Upsteam commit: Date: Mon, 17 May 2021 15:19:23 +0800 eval: Do not cache value of eflag in evaltree Patrick Brünn <P.Bruenn@beckhoff.com> wrote: > Since we are migrating to Debian bullseye, we discovered a new behavior > with our scripts, which look like this: >>cleanup() { >> set +e >> rmdir "" >>} >>set -eu >>trap 'cleanup' EXIT INT TERM >>echo 'Hello world!' > > With old dash v0.5.10.2 this script would return 0 as we expected it. > But since commit 62cf6955f8abe875752d7163f6f3adbc7e49ebae it returns > the last exit code of our cleanup function. ... Thanks for the report. This is actually a fairly old bug with set -e that's just been exposed by the exit status change. What's really happening is that cleanup itself is triggering a set -e exit incorrectly because evaltree cached the value of eflag prior to the function call. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
41beb53787
commit
f415e21a7d
15
shell/ash.c
15
shell/ash.c
@ -9336,8 +9336,7 @@ evaltree(union node *n, int flags)
|
|||||||
case NCMD:
|
case NCMD:
|
||||||
evalfn = evalcommand;
|
evalfn = evalcommand;
|
||||||
checkexit:
|
checkexit:
|
||||||
if (!(flags & EV_TESTED))
|
checkexit = ~flags & EV_TESTED;
|
||||||
checkexit = ~0;
|
|
||||||
goto calleval;
|
goto calleval;
|
||||||
case NFOR:
|
case NFOR:
|
||||||
evalfn = evalfor;
|
evalfn = evalfor;
|
||||||
@ -9359,7 +9358,6 @@ evaltree(union node *n, int flags)
|
|||||||
case NAND:
|
case NAND:
|
||||||
case NOR:
|
case NOR:
|
||||||
case NSEMI: {
|
case NSEMI: {
|
||||||
|
|
||||||
#if NAND + 1 != NOR
|
#if NAND + 1 != NOR
|
||||||
#error NAND + 1 != NOR
|
#error NAND + 1 != NOR
|
||||||
#endif
|
#endif
|
||||||
@ -9387,8 +9385,7 @@ evaltree(union node *n, int flags)
|
|||||||
if (!status) {
|
if (!status) {
|
||||||
n = n->nif.ifpart;
|
n = n->nif.ifpart;
|
||||||
goto evaln;
|
goto evaln;
|
||||||
}
|
} else if (n->nif.elsepart) {
|
||||||
if (n->nif.elsepart) {
|
|
||||||
n = n->nif.elsepart;
|
n = n->nif.elsepart;
|
||||||
goto evaln;
|
goto evaln;
|
||||||
}
|
}
|
||||||
@ -9410,7 +9407,7 @@ evaltree(union node *n, int flags)
|
|||||||
*/
|
*/
|
||||||
dotrap();
|
dotrap();
|
||||||
|
|
||||||
if (checkexit & status) {
|
if (checkexit && status) {
|
||||||
if (trap[NTRAP_ERR] && !in_trap_ERR) {
|
if (trap[NTRAP_ERR] && !in_trap_ERR) {
|
||||||
int err;
|
int err;
|
||||||
struct jmploc *volatile savehandler = exception_handler;
|
struct jmploc *volatile savehandler = exception_handler;
|
||||||
@ -9434,10 +9431,12 @@ evaltree(union node *n, int flags)
|
|||||||
exitstatus = savestatus;
|
exitstatus = savestatus;
|
||||||
}
|
}
|
||||||
if (eflag)
|
if (eflag)
|
||||||
|
goto exexit;
|
||||||
|
}
|
||||||
|
if (flags & EV_EXIT) {
|
||||||
|
exexit:
|
||||||
raise_exception(EXEND);
|
raise_exception(EXEND);
|
||||||
}
|
}
|
||||||
if (flags & EV_EXIT)
|
|
||||||
raise_exception(EXEND);
|
|
||||||
|
|
||||||
popstackmark(&smark);
|
popstackmark(&smark);
|
||||||
TRACE(("leaving evaltree (no interrupts)\n"));
|
TRACE(("leaving evaltree (no interrupts)\n"));
|
||||||
|
2
shell/ash_test/ash-misc/exitcode_trap7.right
Normal file
2
shell/ash_test/ash-misc/exitcode_trap7.right
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Start
|
||||||
|
Ok:0
|
7
shell/ash_test/ash-misc/exitcode_trap7.tests
Executable file
7
shell/ash_test/ash-misc/exitcode_trap7.tests
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
$THIS_SH -c '
|
||||||
|
cleanup() { set +e; false; }
|
||||||
|
set -eu
|
||||||
|
trap cleanup EXIT
|
||||||
|
echo Start
|
||||||
|
'
|
||||||
|
echo Ok:$?
|
Loading…
x
Reference in New Issue
Block a user