diff options
author | Paul Ackersviller <packersv@users.sourceforge.net> | 2007-11-18 19:42:41 +0000 |
---|---|---|
committer | Paul Ackersviller <packersv@users.sourceforge.net> | 2007-11-18 19:42:41 +0000 |
commit | f17fc04c70d3c02bd3781d3834fbb8b0be0a8b33 (patch) | |
tree | 6a00d0c0600b227426670a48ae8c757a8d088c00 | |
parent | d14a675a8459e1e1ae6e9862cb9a38dcceec5c4a (diff) | |
download | zsh-f17fc04c70d3c02bd3781d3834fbb8b0be0a8b33.tar.gz zsh-f17fc04c70d3c02bd3781d3834fbb8b0be0a8b33.tar.xz zsh-f17fc04c70d3c02bd3781d3834fbb8b0be0a8b33.zip |
Merge of 23364: fix race in POSIX signal blocking - use local variables as other forms already do.
-rw-r--r-- | Src/signals.c | 33 | ||||
-rw-r--r-- | Src/signals.h | 57 |
2 files changed, 36 insertions, 54 deletions
diff --git a/Src/signals.c b/Src/signals.c index 7885210cf..0f541b3da 100644 --- a/Src/signals.c +++ b/Src/signals.c @@ -191,15 +191,6 @@ signal_mask(int sig) * set. Return the old signal set. */ /**/ -#ifdef POSIX_SIGNALS - -/**/ -mod_export sigset_t dummy_sigset1, dummy_sigset2; - -/**/ -#else - -/**/ #ifndef BSD_SIGNALS sigset_t @@ -207,7 +198,11 @@ signal_block(sigset_t set) { sigset_t oset; -#ifdef SYSV_SIGNALS +#ifdef POSIX_SIGNALS + sigprocmask(SIG_BLOCK, &set, &oset); + +#else +# ifdef SYSV_SIGNALS int i; oset = blocked_set; @@ -217,7 +212,7 @@ signal_block(sigset_t set) sighold(i); } } -#else /* NO_SIGNAL_BLOCKING */ +# else /* NO_SIGNAL_BLOCKING */ /* We will just ignore signals if the system doesn't have * * the ability to block them. */ int i; @@ -229,7 +224,8 @@ signal_block(sigset_t set) signal_ignore(i); } } -#endif /* SYSV_SIGNALS */ +# endif /* SYSV_SIGNALS */ +#endif /* POSIX_SIGNALS */ return oset; } @@ -237,19 +233,17 @@ signal_block(sigset_t set) /**/ #endif /* BSD_SIGNALS */ -/**/ -#endif /* POSIX_SIGNALS */ - /* Unblock the signals in the given signal * * set. Return the old signal set. */ -#ifndef POSIX_SIGNALS - sigset_t signal_unblock(sigset_t set) { sigset_t oset; - + +#ifdef POSIX_SIGNALS + sigprocmask(SIG_UNBLOCK, &set, &oset); +#else # ifdef BSD_SIGNALS sigfillset(&oset); oset = sigsetmask(oset); @@ -279,12 +273,11 @@ signal_unblock(sigset_t set) } # endif /* SYSV_SIGNALS */ # endif /* BSD_SIGNALS */ +#endif /* POSIX_SIGNALS */ return oset; } -#endif /* POSIX_SIGNALS */ - /* set the process signal mask to * * be the given signal mask */ diff --git a/Src/signals.h b/Src/signals.h index b1970e0f2..9541a1a02 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) @@ -73,48 +72,38 @@ * queue signals, it is probably overkill for zsh to do * * this, but it shouldn't hurt anything to do it anyway. */ -/* Right now I'm queueing all signals, but maybe we only * - * need to queue SIGCHLD. Anybody know? */ - -#define MAX_QUEUE_SIZE 16 +#define MAX_QUEUE_SIZE 128 #define queue_signals() (queueing_enabled++) +#define run_queued_signals() do { \ + while (queue_front != queue_rear) { /* while signals in queue */ \ + sigset_t oset; \ + queue_front = (queue_front + 1) % MAX_QUEUE_SIZE; \ + oset = signal_setmask(signal_mask_queue[queue_front]); \ + zhandler(signal_queue[queue_front]); /* handle queued signal */ \ + signal_setmask(oset); \ + } \ +} while (0) + #define unqueue_signals() do { \ DPUTS(!queueing_enabled, "BUG: unqueue_signals called but not queueing"); \ - if (!--queueing_enabled) { \ - while (queue_front != queue_rear) { /* while signals in queue */ \ - sigset_t oset; \ - queue_front = (queue_front + 1) % MAX_QUEUE_SIZE; \ - oset = signal_setmask(signal_mask_queue[queue_front]); \ - handler(signal_queue[queue_front]); /* handle queued signal */ \ - signal_setmask(oset); \ - } \ - } \ + if (!--queueing_enabled) run_queued_signals(); \ } while (0) +#define queue_signal_level() queueing_enabled -/* Make some signal functions faster. */ +#define dont_queue_signals() do { \ + queueing_enabled = 0; \ + run_queued_signals(); \ +} while (0) -#ifdef POSIX_SIGNALS -#define signal_block(S) \ - ((dummy_sigset1 = (S)), \ - sigprocmask(SIG_BLOCK, &dummy_sigset1, &dummy_sigset2), \ - dummy_sigset2) -#else -# ifdef BSD_SIGNALS +#define restore_queue_signals(q) (queueing_enabled = (q)) + +#ifdef BSD_SIGNALS #define signal_block(S) sigblock(S) -# else -extern sigset_t signal_block _((sigset_t)); -# endif /* BSD_SIGNALS */ -#endif /* POSIX_SIGNALS */ - -#ifdef POSIX_SIGNALS -#define signal_unblock(S) \ - ((dummy_sigset1 = (S)), \ - sigprocmask(SIG_UNBLOCK, &dummy_sigset1, &dummy_sigset2), \ - dummy_sigset2) #else -extern sigset_t signal_unblock _((sigset_t)); -#endif /* POSIX_SIGNALS */ +extern sigset_t signal_block _((sigset_t)); +#endif /* BSD_SIGNALS */ +extern sigset_t signal_unblock _((sigset_t)); |