aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-09-07 01:54:23 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-09-07 02:01:03 +0200
commitf415e21a7dce1d4f4b760fddfaba85c551681e11 (patch)
tree1c126cfd0ff6193b151db4fddaf79fac3d822dfd
parent41beb53787ec798a27f336c4758cb5ebd8f0c75a (diff)
downloadbusybox-w32-f415e21a7dce1d4f4b760fddfaba85c551681e11.tar.gz
busybox-w32-f415e21a7dce1d4f4b760fddfaba85c551681e11.tar.bz2
busybox-w32-f415e21a7dce1d4f4b760fddfaba85c551681e11.zip
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>
-rw-r--r--shell/ash.c15
-rw-r--r--shell/ash_test/ash-misc/exitcode_trap7.right2
-rwxr-xr-xshell/ash_test/ash-misc/exitcode_trap7.tests7
3 files changed, 16 insertions, 8 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 2d2c09ba5..c65f09782 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -9336,8 +9336,7 @@ evaltree(union node *n, int flags)
9336 case NCMD: 9336 case NCMD:
9337 evalfn = evalcommand; 9337 evalfn = evalcommand;
9338 checkexit: 9338 checkexit:
9339 if (!(flags & EV_TESTED)) 9339 checkexit = ~flags & EV_TESTED;
9340 checkexit = ~0;
9341 goto calleval; 9340 goto calleval;
9342 case NFOR: 9341 case NFOR:
9343 evalfn = evalfor; 9342 evalfn = evalfor;
@@ -9359,7 +9358,6 @@ evaltree(union node *n, int flags)
9359 case NAND: 9358 case NAND:
9360 case NOR: 9359 case NOR:
9361 case NSEMI: { 9360 case NSEMI: {
9362
9363#if NAND + 1 != NOR 9361#if NAND + 1 != NOR
9364#error NAND + 1 != NOR 9362#error NAND + 1 != NOR
9365#endif 9363#endif
@@ -9387,8 +9385,7 @@ evaltree(union node *n, int flags)
9387 if (!status) { 9385 if (!status) {
9388 n = n->nif.ifpart; 9386 n = n->nif.ifpart;
9389 goto evaln; 9387 goto evaln;
9390 } 9388 } else if (n->nif.elsepart) {
9391 if (n->nif.elsepart) {
9392 n = n->nif.elsepart; 9389 n = n->nif.elsepart;
9393 goto evaln; 9390 goto evaln;
9394 } 9391 }
@@ -9410,7 +9407,7 @@ evaltree(union node *n, int flags)
9410 */ 9407 */
9411 dotrap(); 9408 dotrap();
9412 9409
9413 if (checkexit & status) { 9410 if (checkexit && status) {
9414 if (trap[NTRAP_ERR] && !in_trap_ERR) { 9411 if (trap[NTRAP_ERR] && !in_trap_ERR) {
9415 int err; 9412 int err;
9416 struct jmploc *volatile savehandler = exception_handler; 9413 struct jmploc *volatile savehandler = exception_handler;
@@ -9434,10 +9431,12 @@ evaltree(union node *n, int flags)
9434 exitstatus = savestatus; 9431 exitstatus = savestatus;
9435 } 9432 }
9436 if (eflag) 9433 if (eflag)
9437 raise_exception(EXEND); 9434 goto exexit;
9438 } 9435 }
9439 if (flags & EV_EXIT) 9436 if (flags & EV_EXIT) {
9437 exexit:
9440 raise_exception(EXEND); 9438 raise_exception(EXEND);
9439 }
9441 9440
9442 popstackmark(&smark); 9441 popstackmark(&smark);
9443 TRACE(("leaving evaltree (no interrupts)\n")); 9442 TRACE(("leaving evaltree (no interrupts)\n"));
diff --git a/shell/ash_test/ash-misc/exitcode_trap7.right b/shell/ash_test/ash-misc/exitcode_trap7.right
new file mode 100644
index 000000000..07d66e9d9
--- /dev/null
+++ b/shell/ash_test/ash-misc/exitcode_trap7.right
@@ -0,0 +1,2 @@
1Start
2Ok:0
diff --git a/shell/ash_test/ash-misc/exitcode_trap7.tests b/shell/ash_test/ash-misc/exitcode_trap7.tests
new file mode 100755
index 000000000..9772a7b8c
--- /dev/null
+++ b/shell/ash_test/ash-misc/exitcode_trap7.tests
@@ -0,0 +1,7 @@
1$THIS_SH -c '
2cleanup() { set +e; false; }
3set -eu
4trap cleanup EXIT
5echo Start
6'
7echo Ok:$?