[git commit] ash: eval: Do not cache value of eflag in evaltree
Denys Vlasenko
vda.linux at googlemail.com
Tue Sep 7 00:01:03 UTC 2021
commit: https://git.busybox.net/busybox/commit/?id=f415e21a7dce1d4f4b760fddfaba85c551681e11
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master
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 at 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 at googlemail.com>
---
shell/ash.c | 15 +++++++--------
shell/ash_test/ash-misc/exitcode_trap7.right | 2 ++
shell/ash_test/ash-misc/exitcode_trap7.tests | 7 +++++++
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)
case NCMD:
evalfn = evalcommand;
checkexit:
- if (!(flags & EV_TESTED))
- checkexit = ~0;
+ checkexit = ~flags & EV_TESTED;
goto calleval;
case NFOR:
evalfn = evalfor;
@@ -9359,7 +9358,6 @@ evaltree(union node *n, int flags)
case NAND:
case NOR:
case NSEMI: {
-
#if NAND + 1 != NOR
#error NAND + 1 != NOR
#endif
@@ -9387,8 +9385,7 @@ evaltree(union node *n, int flags)
if (!status) {
n = n->nif.ifpart;
goto evaln;
- }
- if (n->nif.elsepart) {
+ } else if (n->nif.elsepart) {
n = n->nif.elsepart;
goto evaln;
}
@@ -9410,7 +9407,7 @@ evaltree(union node *n, int flags)
*/
dotrap();
- if (checkexit & status) {
+ if (checkexit && status) {
if (trap[NTRAP_ERR] && !in_trap_ERR) {
int err;
struct jmploc *volatile savehandler = exception_handler;
@@ -9434,10 +9431,12 @@ evaltree(union node *n, int flags)
exitstatus = savestatus;
}
if (eflag)
- raise_exception(EXEND);
+ goto exexit;
}
- if (flags & EV_EXIT)
+ if (flags & EV_EXIT) {
+ exexit:
raise_exception(EXEND);
+ }
popstackmark(&smark);
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 @@
+Start
+Ok: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 @@
+$THIS_SH -c '
+cleanup() { set +e; false; }
+set -eu
+trap cleanup EXIT
+echo Start
+'
+echo Ok:$?
More information about the busybox-cvs
mailing list