diff options
author | jilles <jilles@FreeBSD.org> | 2013-03-03 17:33:59 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2013-03-03 17:33:59 +0000 |
commit | d0155c5dccc3af5494798ad79b42ad906bfd8671 (patch) | |
tree | 8f22588cd3d7dd9680e3d8df2bb3c64c95436187 | |
parent | 82dd943a5ebeb1f62f5815e263e3de810e3fbf55 (diff) | |
download | FreeBSD-src-d0155c5dccc3af5494798ad79b42ad906bfd8671.zip FreeBSD-src-d0155c5dccc3af5494798ad79b42ad906bfd8671.tar.gz |
sh: When executing a trap, keep exit status along with evalskip.
This ensures 'return' in a trap returns the correct status to the caller.
If evalskip is not set or if it is overridden by a previous evalskip, keep
the old behaviour of restoring the exit status from before the trap.
-rw-r--r-- | bin/sh/trap.c | 5 | ||||
-rw-r--r-- | tools/regression/bin/sh/builtins/trap12.0 | 10 |
2 files changed, 13 insertions, 2 deletions
diff --git a/bin/sh/trap.c b/bin/sh/trap.c index 0a9eb60..6c4cbbe 100644 --- a/bin/sh/trap.c +++ b/bin/sh/trap.c @@ -455,7 +455,6 @@ dotrap(void) last_trapsig = i; savestatus = exitstatus; evalstring(trap[i], 0); - exitstatus = savestatus; /* * If such a command was not @@ -464,9 +463,11 @@ dotrap(void) * trap action to have an effect * outside of it. */ - if (prev_evalskip != 0) { + if (evalskip == 0 || + prev_evalskip != 0) { evalskip = prev_evalskip; skipcount = prev_skipcount; + exitstatus = savestatus; } if (i == SIGCHLD) diff --git a/tools/regression/bin/sh/builtins/trap12.0 b/tools/regression/bin/sh/builtins/trap12.0 new file mode 100644 index 0000000..8c62ffd --- /dev/null +++ b/tools/regression/bin/sh/builtins/trap12.0 @@ -0,0 +1,10 @@ +# $FreeBSD$ + +f() { + trap 'return 42' USR1 + kill -USR1 $$ + return 3 +} +f +r=$? +[ "$r" = 42 ] |