diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Src/exec.c | 5 | ||||
-rw-r--r-- | Src/signals.c | 16 |
3 files changed, 24 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog index 4d5402a0b..358fa6f5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2001-03-30 Peter Stephenson <pws@csr.com> + + * 13851: Src/signals.c, Src/exec.c: don't exec final command in + in list if any traps are set, since we don't know whether we will + need to handle them when that command exits. + 2001-03-30 Bart Schaefer <schaefer@zsh.org> * 13846: Test/ztst.zsh: When "make check" is run with output to a diff --git a/Src/exec.c b/Src/exec.c index fa49c3137..073bea456 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -1954,7 +1954,7 @@ execcmd(Estate state, int input, int output, int how, int last1) * be needed after the current command. This is typically the case * * when when the command is the last stage in a subshell, or is the * * last command after the option `-c'. * - * 2) We are not trapping EXIT or ZERR. * + * 2) We don't have any traps set. * * 3) We don't have any files to delete. * * * * The condition above for a `fake exec' will also work for a current * @@ -1966,8 +1966,7 @@ execcmd(Estate state, int input, int output, int how, int last1) if ((how & Z_ASYNC) || (!do_exec && (((is_builtin || is_shfunc) && output) || - (!is_cursh && (last1 != 1 || sigtrapped[SIGZERR] || - sigtrapped[SIGEXIT] || havefiles()))))) { + (!is_cursh && (last1 != 1 || nsigtrapped || havefiles()))))) { pid_t pid; int synch[2]; diff --git a/Src/signals.c b/Src/signals.c index 7ff4fca9d..d664f80c3 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -41,6 +41,11 @@ mod_export int sigtrapped[VSIGCOUNT]; /**/ mod_export Eprog sigfuncs[VSIGCOUNT]; +/* Total count of trapped signals */ + +/**/ +mod_export int nsigtrapped; + /* Variables used by signal queueing */ /**/ @@ -716,6 +721,7 @@ settrap(int sig, Eprog l) sig != SIGCHLD) signal_ignore(sig); } else { + nsigtrapped++; sigtrapped[sig] = ZSIG_TRAPPED; if (sig && sig <= SIGCOUNT && #ifdef SIGWINCH @@ -773,6 +779,8 @@ removetrap(int sig) unqueue_signals(); return NULL; } + if (sigtrapped[sig] & ZSIG_TRAPPED) + nsigtrapped--; sigtrapped[sig] = 0; if (sig == SIGINT && interact) { /* PWS 1995/05/16: added test for interactive, also noholdintr() * @@ -860,6 +868,8 @@ endtrapscope(void) exitfn = sigfuncs[SIGEXIT]; } sigfuncs[SIGEXIT] = NULL; + if (sigtrapped[SIGEXIT] & ZSIG_TRAPPED) + nsigtrapped--; sigtrapped[SIGEXIT] = 0; } @@ -878,6 +888,12 @@ endtrapscope(void) dontsavetrap++; settrap(sig, prog); dontsavetrap--; + /* + * counting of nsigtrapped should presumably be handled + * in settrap... + */ + DPUTS((sigtrapped[sig] ^ st->flags) & ZSIG_TRAPPED, + "BUG: settrap didn't restore correct ZSIG_TRAPPED"); if ((sigtrapped[sig] = st->flags) & ZSIG_FUNC) shfunctab->addnode(shfunctab, ((Shfunc)st->list)->nam, (Shfunc) st->list); |