ash: fix return_in_trap1.tests failure
authorDenys Vlasenko <vda.linux@googlemail.com>
Sat, 1 Oct 2016 21:25:12 +0000 (23:25 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sat, 1 Oct 2016 21:25:12 +0000 (23:25 +0200)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash.c

index d320c38acbba02755b901a486e91211695e660af..b8160433eb88c35046615c01cafcdbe36f3e8e94 100644 (file)
@@ -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"));