/* 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?]
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:
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);
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 */
_mcleanup();
}
#endif
+ TRACE(("End of main reached\n"));
exitshell();
/* NOTREACHED */
}
--- /dev/null
+"$THIS_SH" -c '
+exit_func() {
+ echo "Removing traps"
+ trap - EXIT TERM INT
+ echo "End of exit_func"
+}
+set -e
+trap exit_func EXIT TERM INT
+sleep 2
+exit 77
+' &
+
+sleep 1
+# BUG: ash kills -PGRP, but in non-interactive shell we do not create pgrps!
+# In this case, bash kills by PID, not PGRP.
+kill -TERM %1
+wait
+echo Done: $?
--- /dev/null
+# Note: the inner script is a test which checks for a different bug
+# (ordering between INT handler and exit on "set -e"),
+# but so far I did not figure out how to simulate it non-interactively.
+
+"$THIS_SH" -c '
+exit_func() {
+ echo "Removing traps"
+ trap - EXIT TERM INT
+ echo "End of exit_func"
+}
+set -e
+trap exit_func EXIT TERM INT
+sleep 2
+exit 77
+' &
+
+child=$!
+sleep 1
+kill -TERM $child
+wait
+echo Done: $?