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)
This commit is contained in:
Jilles Tjoelker 2009-06-13 21:10:41 +00:00
parent 53f55a430f
commit 6e28dacfda
3 changed files with 17 additions and 1 deletions

View File

@ -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

View File

@ -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.

View File

@ -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);