1/* $NetBSD$ */ 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 50static sigset_t saved_sigmask; 51static sigset_t block_sigmask; 52static int suspending; 53static int siginit_done; 54 55/* siginit - compute signal mask only once */ 56 57static 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 69void 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 80void 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 102static void gotsig(int sig) 103{ 104 printf("Got signal %d\n", sig); 105} 106 107int 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