From 6e28dacfda496f534bcfc6f2ea2888261fa55be7 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 13 Jun 2009 21:10:41 +0000 Subject: [PATCH] Don't skip forking for an external command if any traps are active. Example: sh -c '(trap "echo trapped" EXIT; sleep 3)' now correctly prints "trapped". With this check, it is no longer necessary to check for -T explicitly in that case. This is a useful bugfix by itself and also important because I plan to skip forking more often. PR: bin/113860 (part of) PR: bin/74404 (part of) Reviewed by: stefanf Approved by: ed (mentor) --- bin/sh/eval.c | 2 +- bin/sh/trap.c | 15 +++++++++++++++ bin/sh/trap.h | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 82e74b88bf0..8554943e889 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -731,7 +731,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) /* Fork off a child process if necessary. */ if (cmd->ncmd.backgnd || (cmdentry.cmdtype == CMDNORMAL - && ((flags & EV_EXIT) == 0 || Tflag)) + && ((flags & EV_EXIT) == 0 || have_traps())) || ((flags & EV_BACKCMD) != 0 && (cmdentry.cmdtype != CMDBUILTIN || cmdentry.u.index == CDCMD diff --git a/bin/sh/trap.c b/bin/sh/trap.c index 099dc11bec6..a0cd0ba14cd 100644 --- a/bin/sh/trap.c +++ b/bin/sh/trap.c @@ -221,6 +221,21 @@ clear_traps(void) } +/* + * Check if we have any traps enabled. + */ +int +have_traps(void) +{ + char *volatile *tp; + + for (tp = trap ; tp <= &trap[NSIG - 1] ; tp++) { + if (*tp && **tp) /* trap not NULL or SIG_IGN */ + return 1; + } + return 0; +} + /* * Set the signal handler for the specified signal. The routine figures * out what it should be set to. diff --git a/bin/sh/trap.h b/bin/sh/trap.h index ccc1ffd4f4d..672ad08d481 100644 --- a/bin/sh/trap.h +++ b/bin/sh/trap.h @@ -39,6 +39,7 @@ extern volatile sig_atomic_t gotwinch; int trapcmd(int, char **); void clear_traps(void); +int have_traps(void); void setsignal(int); void ignoresig(int); void onsig(int);