1 /* $NetBSD: sigdelay.c,v 1.1.1.1 2009/06/23 10:09:00 tron Exp $ */ 2 3 /*++ 4 /* NAME 5 /* sigdelay 3 6 /* SUMMARY 7 /* delay/resume signal delivery 8 /* SYNOPSIS 9 /* #include <sigdelay.h> 10 /* 11 /* void sigdelay() 12 /* 13 /* void sigresume() 14 /* DESCRIPTION 15 /* sigdelay() delays delivery of signals. Signals that 16 /* arrive in the mean time will be queued. 17 /* 18 /* sigresume() resumes delivery of signals. Signals that have 19 /* arrived in the mean time will be delivered. 20 /* DIAGNOSTICS 21 /* All errors are fatal. 22 /* BUGS 23 /* The signal queue may be really short (as in: one per signal type). 24 /* 25 /* Some signals such as SIGKILL cannot be blocked. 26 /* LICENSE 27 /* .ad 28 /* .fi 29 /* The Secure Mailer license must be distributed with this software. 30 /* AUTHOR(S) 31 /* Wietse Venema 32 /* IBM T.J. Watson Research 33 /* P.O. Box 704 34 /* Yorktown Heights, NY 10598, USA 35 /*--*/ 36 37 /* System library. */ 38 39 #include <sys_defs.h> 40 #include <signal.h> 41 42 /* Utility library. */ 43 44 #include "msg.h" 45 #include "posix_signals.h" 46 #include "sigdelay.h" 47 48 /* Application-specific. */ 49 50 static sigset_t saved_sigmask; 51 static sigset_t block_sigmask; 52 static int suspending; 53 static int siginit_done; 54 55 /* siginit - compute signal mask only once */ 56 57 static void siginit(void) 58 { 59 int sig; 60 61 siginit_done = 1; 62 sigemptyset(&block_sigmask); 63 for (sig = 1; sig < NSIG; sig++) 64 sigaddset(&block_sigmask, sig); 65 } 66 67 /* sigresume - deliver delayed signals and disable signal delay */ 68 69 void sigresume(void) 70 { 71 if (suspending != 0) { 72 suspending = 0; 73 if (sigprocmask(SIG_SETMASK, &saved_sigmask, (sigset_t *) 0) < 0) 74 msg_fatal("sigresume: sigprocmask: %m"); 75 } 76 } 77 78 /* sigdelay - save signal mask and block all signals */ 79 80 void sigdelay(void) 81 { 82 if (siginit_done == 0) 83 siginit(); 84 if (suspending == 0) { 85 suspending = 1; 86 if (sigprocmask(SIG_BLOCK, &block_sigmask, &saved_sigmask) < 0) 87 msg_fatal("sigdelay: sigprocmask: %m"); 88 } 89 } 90 91 #ifdef TEST 92 93 /* 94 * Test program - press Ctrl-C twice while signal delivery is delayed, and 95 * see how many signals are delivered when signal delivery is resumed. 96 */ 97 98 #include <stdio.h> 99 #include <unistd.h> 100 #include <stdlib.h> 101 102 static void gotsig(int sig) 103 { 104 printf("Got signal %d\n", sig); 105 } 106 107 int main(int unused_argc, char **unused_argv) 108 { 109 signal(SIGINT, gotsig); 110 signal(SIGQUIT, gotsig); 111 112 printf("Delaying signal delivery\n"); 113 sigdelay(); 114 sleep(5); 115 printf("Resuming signal delivery\n"); 116 sigresume(); 117 exit(0); 118 } 119 120 #endif 121