From 885509c023dadf766f14c6a51d60048c835e1cd7 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Sun, 2 May 2004 19:55:54 +0000 Subject: Fix TRAPS_ASYNC so that it handles signals correctly. --- ChangeLog | 6 ++++++ Doc/Zsh/options.yo | 10 +++++----- Src/jobs.c | 10 ++++------ Src/options.c | 2 +- Src/signals.c | 42 +++++++++++++++++++----------------------- Src/signals.h | 19 ------------------- 6 files changed, 35 insertions(+), 54 deletions(-) diff --git a/ChangeLog b/ChangeLog index c9387d719..b65843471 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-05-02 Peter Stephenson + + * 19858: Doc/Zsh/options.yo, Src/jobs.c, Src/options.c, + Src/signals.c, Src/signals.h: TRAPS_ASYNC option done properly, + not blocking signals during sigsuspend to wait for children. + 2004-05-01 Clint Adams * 19863: Completion/Zsh/Type/_command_names, Doc/Zsh/compsys.yo: diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index 7f398cac6..d67d2b16c 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -1191,11 +1191,11 @@ line. This may be useful with terminals with other cut/paste methods. ) pindex(TRAPS_ASYNC) cindex(traps, asynchronous) -item(tt(TRAPS_ASYNC) )( -While waiting for a program to exit, run traps immediately. Otherwise -the trap is run after the program has exited. Note this does not affect -the point at which traps are run for any case other than when the shell is -waiting for a child process. +item(tt(TRAPS_ASYNC))( +While waiting for a program to exit, handle signals and run traps +immediately. Otherwise the trap is run after a child process has exited. +Note this does not affect the point at which traps are run for any case +other than when the shell is waiting for a child process. ) pindex(TYPESET_SILENT) item(tt(TYPESET_SILENT))( diff --git a/Src/jobs.c b/Src/jobs.c index 7d89a7dbb..e6ce47113 100644 --- a/Src/jobs.c +++ b/Src/jobs.c @@ -971,14 +971,14 @@ waitforpid(pid_t pid) /* child_block() around this loop in case #ifndef WNOHANG */ dont_queue_signals(); - child_block(); /* unblocked in child_suspend() */ + child_block(); /* unblocked in signal_suspend() */ while (!errflag && (kill(pid, 0) >= 0 || errno != ESRCH)) { if (first) first = 0; else kill(pid, SIGCONT); - child_suspend(SIGINT); + signal_suspend(SIGCHLD, SIGINT); child_block(); } child_unblock(); @@ -995,8 +995,7 @@ zwaitjob(int job, int sig) Job jn = jobtab + job; dont_queue_signals(); - queue_traps(); - child_block(); /* unblocked during child_suspend() */ + child_block(); /* unblocked during signal_suspend() */ if (jn->procs || jn->auxprocs) { /* if any forks were done */ jn->stat |= STAT_LOCKED; if (jn->stat & STAT_CHANGED) @@ -1004,7 +1003,7 @@ zwaitjob(int job, int sig) while (!errflag && jn->stat && !(jn->stat & STAT_DONE) && !(interact && (jn->stat & STAT_STOPPED))) { - child_suspend(sig); + signal_suspend(SIGCHLD, sig); /* Commenting this out makes ^C-ing a job started by a function stop the whole function again. But I guess it will stop something else from working properly, we have to find out @@ -1026,7 +1025,6 @@ zwaitjob(int job, int sig) numpipestats = 1; } child_unblock(); - dont_queue_traps(); restore_queue_signals(q); } diff --git a/Src/options.c b/Src/options.c index 7fd9906ee..1172f4728 100644 --- a/Src/options.c +++ b/Src/options.c @@ -203,7 +203,7 @@ static struct optname optns[] = { {NULL, "singlelinezle", OPT_KSH, SINGLELINEZLE}, {NULL, "sunkeyboardhack", 0, SUNKEYBOARDHACK}, {NULL, "transientrprompt", 0, TRANSIENTRPROMPT}, -{NULL, "trapsasync", OPT_EMULATE|OPT_NONBOURNE, TRAPSASYNC}, +{NULL, "trapsasync", 0, TRAPSASYNC}, {NULL, "typesetsilent", OPT_EMULATE|OPT_BOURNE, TYPESETSILENT}, {NULL, "unset", OPT_EMULATE|OPT_BSHELL, UNSET}, {NULL, "verbose", 0, VERBOSE}, diff --git a/Src/signals.c b/Src/signals.c index 25febc85d..1c134aaa6 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -350,11 +350,15 @@ signal_suspend(int sig, int sig2) sigset_t oset; #endif /* BROKEN_POSIX_SIGSUSPEND */ - sigfillset(&set); - sigdelset(&set, sig); - sigdelset(&set, SIGHUP); /* still don't know why we add this? */ - if (sig2) - sigdelset(&set, sig2); + if (isset(TRAPSASYNC)) { + sigemptyset(&set); + } else { + sigfillset(&set); + sigdelset(&set, sig); + sigdelset(&set, SIGHUP); /* still don't know why we add this? */ + if (sig2) + sigdelset(&set, sig2); + } #ifdef BROKEN_POSIX_SIGSUSPEND sigprocmask(SIG_SETMASK, &set, &oset); pause(); @@ -366,11 +370,15 @@ signal_suspend(int sig, int sig2) # ifdef BSD_SIGNALS sigset_t set; - sigfillset(&set); - sigdelset(&set, sig); - if (sig2) - sigdelset(&set, sig2); - ret = sigpause(set); + if (isset(TRAPSASYNC)) { + sigemptyset(&set); + } else { + sigfillset(&set); + sigdelset(&set, sig); + if (sig2) + sigdelset(&set, sig2); + ret = sigpause(set); + } # else # ifdef SYSV_SIGNALS ret = sigpause(sig); @@ -426,7 +434,7 @@ zhandler(int sig) do_jump = suspend_longjmp; /* do we need to longjmp to signal_suspend */ suspend_longjmp = 0; /* In case a SIGCHLD somehow arrives */ - if (sig == SIGCHLD) { /* Traps can cause nested child_suspend() */ + if (sig == SIGCHLD) { /* Traps can cause nested signal_suspend() */ if (do_jump) jump_to = suspend_jmp_buf; /* Copy suspend_jmp_buf */ } @@ -1065,17 +1073,5 @@ dotrap(int sig) if ((sigtrapped[sig] & ZSIG_IGNORED) || !sigfuncs[sig] || errflag) return; - /* Adapted from signal queueing in zhandler */ - if (trap_queueing_enabled && !isset(TRAPSASYNC)) { - int temp_rear = ++trap_queue_rear % MAX_QUEUE_SIZE; - - DPUTS(temp_rear == trap_queue_front, "BUG: trap queue full"); - if (temp_rear != trap_queue_front) { - trap_queue_rear = temp_rear; - trap_queue[trap_queue_rear] = sig; - } - return; - } - dotrapargs(sig, sigtrapped+sig, sigfuncs[sig]); } diff --git a/Src/signals.h b/Src/signals.h index e86906ebc..999040908 100644 --- a/Src/signals.h +++ b/Src/signals.h @@ -58,7 +58,6 @@ #define child_block() signal_block(sigchld_mask) #define child_unblock() signal_unblock(sigchld_mask) -#define child_suspend(S) signal_suspend(SIGCHLD, S) /* ignore a signal */ #define signal_ignore(S) signal(S, SIG_IGN) @@ -101,24 +100,6 @@ #define restore_queue_signals(q) (queueing_enabled = (q)) -/* - * Similar (but simpler) mechanism used for queueing traps. - * Only needed if NO_TRAPS_ASYNC is set. - */ -#define queue_traps() (trap_queueing_enabled++) - -#define run_queued_traps() do { \ - while (trap_queue_front != trap_queue_rear) { /* while traps in queue */ \ - trap_queue_front = (trap_queue_front + 1) % MAX_QUEUE_SIZE; \ - dotrap(trap_queue[trap_queue_front]); /* handle queued trap */ \ - } \ -} while (0) - -#define dont_queue_traps() do { \ - trap_queueing_enabled = 0; \ - run_queued_traps(); \ -} while (0) - /* Make some signal functions faster. */ #ifdef POSIX_SIGNALS -- cgit 1.4.1