about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
authorPaul Ackersviller <packersv@users.sourceforge.net>2007-11-18 19:42:41 +0000
committerPaul Ackersviller <packersv@users.sourceforge.net>2007-11-18 19:42:41 +0000
commitf17fc04c70d3c02bd3781d3834fbb8b0be0a8b33 (patch)
tree6a00d0c0600b227426670a48ae8c757a8d088c00 /Src
parentd14a675a8459e1e1ae6e9862cb9a38dcceec5c4a (diff)
downloadzsh-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.
Diffstat (limited to 'Src')
-rw-r--r--Src/signals.c33
-rw-r--r--Src/signals.h57
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));