[git commit] ash: fix return_in_trap1.tests failure

Denys Vlasenko vda.linux at googlemail.com
Sat Oct 1 21:25:12 UTC 2016


commit: https://git.busybox.net/busybox/commit/?id=b98b4c103f32a3915557532806ba5203a3de6ee2
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 shell/ash.c | 51 ++++++++++++++++++++++++++++-----------------------
 1 file changed, 28 insertions(+), 23 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index d320c38..b816043 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"));


More information about the busybox-cvs mailing list