diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/eval.c | 4 | ||||
-rw-r--r-- | src/trap.c | 19 | ||||
-rw-r--r-- | src/trap.h | 7 |
4 files changed, 26 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog index 650899a..969d6be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-27 Jilles Tjoelker <jilles@stack.nl> + + * Force fork if any trap is set, not just on EXIT. + 2010-05-27 Herbert Xu <herbert@gondor.apana.org.au> * Fix poplocalvar on abnormal exit from function. diff --git a/src/eval.c b/src/eval.c index d5c1e6c..439f881 100644 --- a/src/eval.c +++ b/src/eval.c @@ -449,7 +449,7 @@ evalsubshell(union node *n, int flags) int status; expredir(n->nredir.redirect); - if (!backgnd && flags & EV_EXIT && !trap[0]) + if (!backgnd && flags & EV_EXIT && !have_traps()) goto nofork; INTOFF; jp = makejob(n, 1); @@ -836,7 +836,7 @@ bail: switch (cmdentry.cmdtype) { default: /* Fork off a child process if necessary. */ - if (!(flags & EV_EXIT) || trap[0]) { + if (!(flags & EV_EXIT) || have_traps()) { INTOFF; jp = makejob(cmd, 1); if (forkshell(jp, cmd, FORK_FG) != 0) { diff --git a/src/trap.c b/src/trap.c index 3f93c46..ba32da6 100644 --- a/src/trap.c +++ b/src/trap.c @@ -69,7 +69,9 @@ /* trap handler commands */ -char *trap[NSIG]; +static char *trap[NSIG]; +/* number of non-null traps */ +int trapcnt; /* current value of signal */ char sigmode[NSIG - 1]; /* indicates specified signal received */ @@ -125,11 +127,17 @@ trapcmd(int argc, char **argv) if (action) { if (action[0] == '-' && action[1] == '\0') action = NULL; - else + else { + if (*action) + trapcnt++; action = savestr(action); + } } - if (trap[signo]) + if (trap[signo]) { + if (*trap[signo]) + trapcnt--; ckfree(trap[signo]); + } trap[signo] = action; if (signo != 0) setsignal(signo); @@ -150,16 +158,17 @@ clear_traps(void) { char **tp; + INTOFF; for (tp = trap ; tp < &trap[NSIG] ; tp++) { if (*tp && **tp) { /* trap not NULL or SIG_IGN */ - INTOFF; ckfree(*tp); *tp = NULL; if (tp != &trap[0]) setsignal(tp - trap); - INTON; } } + trapcnt = 0; + INTON; } diff --git a/src/trap.h b/src/trap.h index f19a66b..50fc3ed 100644 --- a/src/trap.h +++ b/src/trap.h @@ -36,7 +36,7 @@ #include <signal.h> -extern char *trap[]; +extern int trapcnt; extern char sigmode[]; extern volatile sig_atomic_t pendingsigs; @@ -49,3 +49,8 @@ int dotrap(void); void setinteractive(int); void exitshell(void) __attribute__((__noreturn__)); int decode_signal(const char *, int); + +static inline int have_traps(void) +{ + return trapcnt; +} |