summaryrefslogtreecommitdiffhomepage
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-10-01 23:25:12 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-10-01 23:25:12 +0200
commitb98b4c103f32a3915557532806ba5203a3de6ee2 (patch)
tree253e3ead30cd00383e2edc38ed1e4a80867818fb /shell
parent3ed7e2749a3f9fd315d8f46a3b0a25ff10caf726 (diff)
ash: fix return_in_trap1.tests failure
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c51
1 files changed, 28 insertions, 23 deletions
diff --git a/shell/ash.c b/shell/ash.c
index d320c38ac..b8160433e 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -8420,43 +8420,46 @@ static int evalstring(char *s, int flags);
* Perhaps we should avoid entering new trap handlers
* while we are executing a trap handler. [is it a TODO?]
*/
-static int
+static void
dotrap(void)
{
uint8_t *g;
int sig;
- uint8_t savestatus;
+ uint8_t last_status;
+
+ if (!pending_sig)
+ return;
- savestatus = exitstatus;
+ last_status = exitstatus;
pending_sig = 0;
xbarrier();
TRACE(("dotrap entered\n"));
for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) {
- char *t;
+ char *p;
- if (*g == 0)
+ if (!*g)
continue;
- t = trap[sig];
+
+ if (evalskip) {
+ pending_sig = sig;
+ break;
+ }
+
+ p = trap[sig];
/* non-trapped SIGINT is handled separately by raise_interrupt,
* don't upset it by resetting gotsig[SIGINT-1] */
- if (sig == SIGINT && !t)
+ if (sig == SIGINT && !p)
continue;
- TRACE(("sig %d is active, will run handler '%s'\n", sig, t));
+ TRACE(("sig %d is active, will run handler '%s'\n", sig, p));
*g = 0;
- if (!t)
+ if (!p)
continue;
- evalstring(t, 0);
- exitstatus = savestatus;
- if (evalskip) {
- TRACE(("dotrap returns %d\n", evalskip));
- return evalskip;
- }
+ evalstring(p, 0);
}
-
- TRACE(("dotrap returns 0\n"));
- return 0;
+ exitstatus = last_status;
+ TRACE(("dotrap returns\n"));
}
/* forward declarations - evaluation is fairly recursive business... */
@@ -8492,6 +8495,8 @@ evaltree(union node *n, int flags)
}
TRACE(("evaltree(%p: %d, %d) called\n", n, n->type, flags));
+ dotrap();
+
exception_handler = &jmploc;
{
int err = setjmp(jmploc.loc);
@@ -8609,12 +8614,12 @@ evaltree(union node *n, int flags)
/* Order of checks below is important:
* signal handlers trigger before exit caused by "set -e".
*/
- if ((pending_sig && dotrap())
- || (checkexit & status)
- || (flags & EV_EXIT)
- ) {
+ dotrap();
+
+ if (checkexit & status)
+ raise_exception(EXEXIT);
+ if (flags & EV_EXIT)
raise_exception(EXEXIT);
- }
RESTORE_INT(int_level);
TRACE(("leaving evaltree (no interrupts)\n"));