On 29/11/2018 15:45, Martijn Dekker wrote:
Op 27-11-18 om 17:24 schreef Martijn Dekker:
Big bad bug: it appears that subshells always return status 0 in traps.
As posted elsewhere, looks like the problem is simply that savestatus
("/* exit status of last command outside traps */") isn't reset to -1
upon resetting traps when forking a subshell.
That's part of it, but not the whole story. Herbert Xu's comment about
exitshell() was right, that is still a problem. A testcase for this is
trap '(true) || echo bug' EXIT
Your patch can be extended to handle that though, by skipping
exitshell()'s handler if savestatus got reset to -1.
Cheers,
Harald van Dijk
diff --git a/src/trap.c b/src/trap.c
index ab0ecd46..eef44f1d 100644
--- a/src/trap.c
+++ b/src/trap.c
@@ -169,6 +169,7 @@ clear_traps(void)
}
trapcnt = 0;
INTON;
+ savestatus = -1;
}
@@ -387,11 +388,18 @@ exitshell(void)
{
struct jmploc loc;
char *p;
+ struct jmploc *volatile savehandler;
savestatus = exitstatus;
TRACE(("pid %d, exitshell(%d)\n", getpid(), savestatus));
- if (setjmp(loc.loc))
+ savehandler = handler;
+ if (setjmp(loc.loc)) {
+ if (savestatus == -1) {
+ handler = savehandler;
+ longjmp(handler->loc, 1);
+ }
goto out;
+ }
handler = &loc;
if ((p = trap[0])) {
trap[0] = NULL;