Postfix3.3.1
sigdelay.c
[詳解]
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 
48 static sigset_t saved_sigmask;
49 static sigset_t block_sigmask;
50 static int suspending;
51 static int siginit_done;
52 
53 /* siginit - compute signal mask only once */
54 
55 static 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 
67 void 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 
78 void 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 
100 static void gotsig(int sig)
101 {
102  printf("Got signal %d\n", sig);
103 }
104 
105 int 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
int main(int argc, char **argv)
Definition: anvil.c:1010
void sigresume(void)
Definition: sigdelay.c:67
void sigdelay(void)
Definition: sigdelay.c:78
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249