aboutsummaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-09-25 17:15:13 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-09-25 17:15:13 +0200
commitb563f62bbb1c9a6d931924f8fd7c3e52bb3d5875 (patch)
tree617e5a8de03257f9695fd10a496601c607f6803d /shell/ash.c
parent5b3151c201f4a67e998ec054d653e8177679d505 (diff)
downloadbusybox-b563f62bbb1c9a6d931924f8fd7c3e52bb3d5875.tar.gz
ash: fix signal and "set -e" interaction
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 9089adc63..ea835527e 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -8214,7 +8214,7 @@ static int evalstring(char *s, int mask);
/* Called to execute a trap.
* Single callsite - at the end of evaltree().
- * If we return non-zero, exaltree raises EXEXIT exception.
+ * If we return non-zero, evaltree raises EXEXIT exception.
*
* Perhaps we should avoid entering new trap handlers
* while we are executing a trap handler. [is it a TODO?]
@@ -8404,11 +8404,15 @@ evaltree(union node *n, int flags)
out:
exception_handler = savehandler;
+
out1:
+ /* Order of checks below is important:
+ * signal handlers trigger before exit caused by "set -e".
+ */
+ if (pending_sig && dotrap())
+ goto exexit;
if (checkexit & exitstatus)
evalskip |= SKIPEVAL;
- else if (pending_sig && dotrap())
- goto exexit;
if (flags & EV_EXIT) {
exexit:
@@ -8740,7 +8744,7 @@ poplocalvars(void)
while ((lvp = localvars) != NULL) {
localvars = lvp->next;
vp = lvp->vp;
- TRACE(("poplocalvar %s\n", vp ? vp->text : "-"));
+ TRACE(("poplocalvar %s\n", vp ? vp->var_text : "-"));
if (vp == NULL) { /* $- saved */
memcpy(optlist, lvp->text, sizeof(optlist));
free((char*)lvp->text);
@@ -13009,10 +13013,12 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
if (e == EXERROR)
exitstatus = 2;
s = state;
- if (e == EXEXIT || s == 0 || iflag == 0 || shlvl)
+ if (e == EXEXIT || s == 0 || iflag == 0 || shlvl) {
exitshell();
- if (e == EXINT)
+ }
+ if (e == EXINT) {
outcslow('\n', stderr);
+ }
popstackmark(&smark);
FORCE_INT_ON; /* enable interrupts */
@@ -13105,6 +13111,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
_mcleanup();
}
#endif
+ TRACE(("End of main reached\n"));
exitshell();
/* NOTREACHED */
}