summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2021-05-17 15:19:23 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2021-06-04 11:35:44 +0800
commitde368ab886309d326a5984e565c7102cdf8b7858 (patch)
tree558e915222714a4b384f4d7c8689a93bc42101bd
parent802ebd48c8febb1c1b4ce4e438518bf64677c078 (diff)
downloaddash-de368ab886309d326a5984e565c7102cdf8b7858.tar.gz
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: >>#!/bin/sh >>cleanup() { >> set +e^M >> 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. > Reverting that commit gives a merge conflict, but it seems to fix _our_ > problem. As that topic appears too complex to us I want to ask the > experts here: > > Is this change in behavior intended, by dash? > > Our workaround at the moment would be: >>trap 'cleanup || true' EXIT INT TERM 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. This patch should fix the problem. Reported-by: Patrick Brünn <P.Bruenn@beckhoff.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Tested-by: Patrick Brünn <P.Bruenn@beckhoff.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--src/eval.c12
1 files changed, 2 insertions, 10 deletions
diff --git a/src/eval.c b/src/eval.c
index 9476fbb..3337f71 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -252,18 +252,10 @@ evaltree(union node *n, int flags)
popredir(0);
goto setstatus;
case NCMD:
-#ifdef notyet
- if (eflag && !(flags & EV_TESTED))
- checkexit = ~0;
- status = evalcommand(n, flags, (struct backcmd *)NULL);
- goto setstatus;
-#else
evalfn = evalcommand;
checkexit:
- if (eflag && !(flags & EV_TESTED))
- checkexit = ~0;
+ checkexit = ~flags & EV_TESTED;
goto calleval;
-#endif
case NFOR:
evalfn = evalfor;
goto calleval;
@@ -323,7 +315,7 @@ setstatus:
out:
dotrap();
- if (checkexit & status)
+ if (eflag && checkexit && status)
goto exexit;
if (flags & EV_EXIT) {