diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-10-01 23:25:12 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-10-01 23:25:12 +0200 |
commit | b98b4c103f32a3915557532806ba5203a3de6ee2 (patch) | |
tree | 253e3ead30cd00383e2edc38ed1e4a80867818fb | |
parent | 3ed7e2749a3f9fd315d8f46a3b0a25ff10caf726 (diff) | |
download | busybox-w32-b98b4c103f32a3915557532806ba5203a3de6ee2.tar.gz busybox-w32-b98b4c103f32a3915557532806ba5203a3de6ee2.tar.bz2 busybox-w32-b98b4c103f32a3915557532806ba5203a3de6ee2.zip |
ash: fix return_in_trap1.tests failure
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/ash.c | 51 |
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); | |||
8420 | * Perhaps we should avoid entering new trap handlers | 8420 | * Perhaps we should avoid entering new trap handlers |
8421 | * while we are executing a trap handler. [is it a TODO?] | 8421 | * while we are executing a trap handler. [is it a TODO?] |
8422 | */ | 8422 | */ |
8423 | static int | 8423 | static void |
8424 | dotrap(void) | 8424 | dotrap(void) |
8425 | { | 8425 | { |
8426 | uint8_t *g; | 8426 | uint8_t *g; |
8427 | int sig; | 8427 | int sig; |
8428 | uint8_t savestatus; | 8428 | uint8_t last_status; |
8429 | |||
8430 | if (!pending_sig) | ||
8431 | return; | ||
8429 | 8432 | ||
8430 | savestatus = exitstatus; | 8433 | last_status = exitstatus; |
8431 | pending_sig = 0; | 8434 | pending_sig = 0; |
8432 | xbarrier(); | 8435 | xbarrier(); |
8433 | 8436 | ||
8434 | TRACE(("dotrap entered\n")); | 8437 | TRACE(("dotrap entered\n")); |
8435 | for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) { | 8438 | for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) { |
8436 | char *t; | 8439 | char *p; |
8437 | 8440 | ||
8438 | if (*g == 0) | 8441 | if (!*g) |
8439 | continue; | 8442 | continue; |
8440 | t = trap[sig]; | 8443 | |
8444 | if (evalskip) { | ||
8445 | pending_sig = sig; | ||
8446 | break; | ||
8447 | } | ||
8448 | |||
8449 | p = trap[sig]; | ||
8441 | /* non-trapped SIGINT is handled separately by raise_interrupt, | 8450 | /* non-trapped SIGINT is handled separately by raise_interrupt, |
8442 | * don't upset it by resetting gotsig[SIGINT-1] */ | 8451 | * don't upset it by resetting gotsig[SIGINT-1] */ |
8443 | if (sig == SIGINT && !t) | 8452 | if (sig == SIGINT && !p) |
8444 | continue; | 8453 | continue; |
8445 | 8454 | ||
8446 | TRACE(("sig %d is active, will run handler '%s'\n", sig, t)); | 8455 | TRACE(("sig %d is active, will run handler '%s'\n", sig, p)); |
8447 | *g = 0; | 8456 | *g = 0; |
8448 | if (!t) | 8457 | if (!p) |
8449 | continue; | 8458 | continue; |
8450 | evalstring(t, 0); | 8459 | evalstring(p, 0); |
8451 | exitstatus = savestatus; | ||
8452 | if (evalskip) { | ||
8453 | TRACE(("dotrap returns %d\n", evalskip)); | ||
8454 | return evalskip; | ||
8455 | } | ||
8456 | } | 8460 | } |
8457 | 8461 | exitstatus = last_status; | |
8458 | TRACE(("dotrap returns 0\n")); | 8462 | TRACE(("dotrap returns\n")); |
8459 | return 0; | ||
8460 | } | 8463 | } |
8461 | 8464 | ||
8462 | /* forward declarations - evaluation is fairly recursive business... */ | 8465 | /* forward declarations - evaluation is fairly recursive business... */ |
@@ -8492,6 +8495,8 @@ evaltree(union node *n, int flags) | |||
8492 | } | 8495 | } |
8493 | TRACE(("evaltree(%p: %d, %d) called\n", n, n->type, flags)); | 8496 | TRACE(("evaltree(%p: %d, %d) called\n", n, n->type, flags)); |
8494 | 8497 | ||
8498 | dotrap(); | ||
8499 | |||
8495 | exception_handler = &jmploc; | 8500 | exception_handler = &jmploc; |
8496 | { | 8501 | { |
8497 | int err = setjmp(jmploc.loc); | 8502 | int err = setjmp(jmploc.loc); |
@@ -8609,12 +8614,12 @@ evaltree(union node *n, int flags) | |||
8609 | /* Order of checks below is important: | 8614 | /* Order of checks below is important: |
8610 | * signal handlers trigger before exit caused by "set -e". | 8615 | * signal handlers trigger before exit caused by "set -e". |
8611 | */ | 8616 | */ |
8612 | if ((pending_sig && dotrap()) | 8617 | dotrap(); |
8613 | || (checkexit & status) | 8618 | |
8614 | || (flags & EV_EXIT) | 8619 | if (checkexit & status) |
8615 | ) { | 8620 | raise_exception(EXEXIT); |
8621 | if (flags & EV_EXIT) | ||
8616 | raise_exception(EXEXIT); | 8622 | raise_exception(EXEXIT); |
8617 | } | ||
8618 | 8623 | ||
8619 | RESTORE_INT(int_level); | 8624 | RESTORE_INT(int_level); |
8620 | TRACE(("leaving evaltree (no interrupts)\n")); | 8625 | TRACE(("leaving evaltree (no interrupts)\n")); |