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