Postfix3.3.1
master_sig.c
[詳解]
1 /*++
2 /* NAME
3 /* master_sig 3
4 /* SUMMARY
5 /* Postfix master - signal processing
6 /* SYNOPSIS
7 /* #include "master.h"
8 /*
9 /* int master_gotsighup;
10 /* int master_gotsigchld;
11 /*
12 /* int master_sigsetup()
13 /* DESCRIPTION
14 /* This module implements the master process signal handling interface.
15 /*
16 /* master_gotsighup (master_gotsigchld) is set to SIGHUP (SIGCHLD)
17 /* when the process receives a hangup (child death) signal.
18 /*
19 /* master_sigsetup() enables processing of hangup and child death signals.
20 /* Receipt of SIGINT, SIGQUIT, SIGSEGV, SIGILL, or SIGTERM
21 /* is interpreted as a request for termination. Child processes are
22 /* notified of the master\'s demise by sending them a SIGTERM signal.
23 /* DIAGNOSTICS
24 /* BUGS
25 /* Need a way to register cleanup actions.
26 /* SEE ALSO
27 /* LICENSE
28 /* .ad
29 /* .fi
30 /* The Secure Mailer license must be distributed with this software.
31 /* AUTHOR(S)
32 /* Wietse Venema
33 /* IBM T.J. Watson Research
34 /* P.O. Box 704
35 /* Yorktown Heights, NY 10598, USA
36 /*--*/
37 
38 /* System libraries. */
39 
40 #include <sys_defs.h>
41 #include <signal.h>
42 #include <unistd.h>
43 
44 /* Utility library. */
45 
46 #include <msg.h>
47 #include <posix_signals.h>
48 #include <killme_after.h>
49 
50 /* Application-specific. */
51 
52 #include "master.h"
53 
54 #ifdef USE_SIG_RETURN
55 #include <sys/syscall.h>
56 #undef USE_SIG_PIPE
57 #else
58 #define USE_SIG_PIPE
59 #endif
60 
61 /* Local stuff. */
62 
63 #ifdef USE_SIG_PIPE
64 #include <errno.h>
65 #include <fcntl.h>
66 #include <iostuff.h>
67 #include <events.h>
68 
70 
71 #define SIG_PIPE_WRITE_FD master_sig_pipe[1]
72 #define SIG_PIPE_READ_FD master_sig_pipe[0]
73 #endif
74 
77 
78 #ifdef USE_SIG_RETURN
79 
80 /* master_sighup - register arrival of hangup signal */
81 
82 static void master_sighup(int sig)
83 {
84 
85  /*
86  * WARNING WARNING WARNING.
87  *
88  * This code runs at unpredictable moments, as a signal handler. Don't put
89  * any code here other than for setting a global flag.
90  */
91  master_gotsighup = sig;
92 }
93 
94 /* master_sigchld - register arrival of child death signal */
95 
96 static void master_sigchld(int sig, int code, struct sigcontext * scp)
97 {
98 
99  /*
100  * WARNING WARNING WARNING.
101  *
102  * This code runs at unpredictable moments, as a signal handler. Don't put
103  * any code here other than for setting a global flag, or code that is
104  * intended to be run within a signal handler.
105  */
106  master_gotsigchld = sig;
107  if (scp != NULL && scp->sc_syscall == SYS_select) {
108  scp->sc_syscall_action = SIG_RETURN;
109 #ifndef SA_RESTART
110  } else if (scp != NULL) {
111  scp->sc_syscall_action = SIG_RESTART;
112 #endif
113  }
114 }
115 
116 #else
117 
118 /* master_sighup - register arrival of hangup signal */
119 
120 static void master_sighup(int sig)
121 {
122  int saved_errno = errno;
123 
124  /*
125  * WARNING WARNING WARNING.
126  *
127  * This code runs at unpredictable moments, as a signal handler. Don't put
128  * any code here other than for setting a global flag, or code that is
129  * intended to be run within a signal handler. Restore errno in case we
130  * are interrupting the epilog of a failed system call.
131  */
132  master_gotsighup = sig;
133  if (write(SIG_PIPE_WRITE_FD, "", 1) != 1)
134  msg_warn("write to SIG_PIPE_WRITE_FD failed: %m");
135  errno = saved_errno;
136 }
137 
138 /* master_sigchld - force wakeup from select() */
139 
140 static void master_sigchld(int unused_sig)
141 {
142  int saved_errno = errno;
143 
144  /*
145  * WARNING WARNING WARNING.
146  *
147  * This code runs at unpredictable moments, as a signal handler. Don't put
148  * any code here other than for setting a global flag, or code that is
149  * intended to be run within a signal handler. Restore errno in case we
150  * are interrupting the epilog of a failed system call.
151  */
152  master_gotsigchld = 1;
153  if (write(SIG_PIPE_WRITE_FD, "", 1) != 1)
154  msg_warn("write to SIG_PIPE_WRITE_FD failed: %m");
155  errno = saved_errno;
156 }
157 
158 /* master_sig_event - called upon return from select() */
159 
160 static void master_sig_event(int unused_event, void *unused_context)
161 {
162  char c[1];
163 
164  while (read(SIG_PIPE_READ_FD, c, 1) > 0)
165  /* void */ ;
166 }
167 
168 #endif
169 
170 /* master_sigdeath - die, women and children first */
171 
172 static void master_sigdeath(int sig)
173 {
174  const char *myname = "master_sigdeath";
175  struct sigaction action;
176  pid_t pid = getpid();
177 
178  /*
179  * Set alarm clock here for suicide after 5s.
180  */
181  killme_after(5);
182 
183  /*
184  * Terminate all processes in our process group, except ourselves.
185  */
186  sigemptyset(&action.sa_mask);
187  action.sa_flags = 0;
188  action.sa_handler = SIG_IGN;
189  if (sigaction(SIGTERM, &action, (struct sigaction *) 0) < 0)
190  msg_fatal("%s: sigaction: %m", myname);
191  if (kill(-pid, SIGTERM) < 0)
192  msg_fatal("%s: kill process group: %m", myname);
193 
194  /*
195  * XXX We're running from a signal handler, and should not call complex
196  * routines at all, but it would be even worse to silently terminate
197  * without informing the sysadmin. For this reason, msg(3) was made safe
198  * for usage by signal handlers that terminate the process.
199  */
200  msg_info("terminating on signal %d", sig);
201 
202  /*
203  * Undocumented: when a process runs with PID 1, Linux won't deliver a
204  * signal unless the process specifies a handler (i.e. SIG_DFL is treated
205  * as SIG_IGN).
206  */
207  if (init_mode)
208  /* Don't call exit() from a signal handler. */
209  _exit(0);
210 
211  /*
212  * Deliver the signal to ourselves and clean up. XXX We're running as a
213  * signal handler and really should not be doing complicated things...
214  */
215  sigemptyset(&action.sa_mask);
216  action.sa_flags = 0;
217  action.sa_handler = SIG_DFL;
218  if (sigaction(sig, &action, (struct sigaction *) 0) < 0)
219  msg_fatal("%s: sigaction: %m", myname);
220  if (kill(pid, sig) < 0)
221  msg_fatal("%s: kill myself: %m", myname);
222 }
223 
224 /* master_sigsetup - set up signal handlers */
225 
226 void master_sigsetup(void)
227 {
228  const char *myname = "master_sigsetup";
229  struct sigaction action;
230  static int sigs[] = {
231  SIGINT, SIGQUIT, SIGILL, SIGBUS, SIGSEGV, SIGTERM,
232  };
233  unsigned i;
234 
235  sigemptyset(&action.sa_mask);
236  action.sa_flags = 0;
237 
238  /*
239  * Prepare to kill our children when we receive any of the above signals.
240  */
241  action.sa_handler = master_sigdeath;
242  for (i = 0; i < sizeof(sigs) / sizeof(sigs[0]); i++)
243  if (sigaction(sigs[i], &action, (struct sigaction *) 0) < 0)
244  msg_fatal("%s: sigaction(%d): %m", myname, sigs[i]);
245 
246 #ifdef USE_SIG_PIPE
247  if (pipe(master_sig_pipe))
248  msg_fatal("pipe: %m");
253  event_enable_read(SIG_PIPE_READ_FD, master_sig_event, (void *) 0);
254 #endif
255 
256  /*
257  * Intercept SIGHUP (re-read config file) and SIGCHLD (child exit).
258  */
259 #ifdef SA_RESTART
260  action.sa_flags |= SA_RESTART;
261 #endif
262  action.sa_handler = master_sighup;
263  if (sigaction(SIGHUP, &action, (struct sigaction *) 0) < 0)
264  msg_fatal("%s: sigaction(%d): %m", myname, SIGHUP);
265 
266  action.sa_flags |= SA_NOCLDSTOP;
267  action.sa_handler = master_sigchld;
268  if (sigaction(SIGCHLD, &action, (struct sigaction *) 0) < 0)
269  msg_fatal("%s: sigaction(%d): %m", myname, SIGCHLD);
270 }
void event_enable_read(int fd, EVENT_NOTIFY_RDWR_FN callback, void *context)
Definition: events.c:729
int init_mode
Definition: master.c:238
int master_sig_pipe[2]
Definition: master_sig.c:69
int master_gotsigchld
Definition: master_sig.c:75
int master_gotsighup
Definition: master_sig.c:76
void killme_after(unsigned int seconds)
Definition: killme_after.c:41
void msg_warn(const char *fmt,...)
Definition: msg.c:215
#define SIG_PIPE_READ_FD
Definition: master_sig.c:72
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
#define SIG_PIPE_WRITE_FD
Definition: master_sig.c:71
#define NON_BLOCKING
Definition: iostuff.h:49
int non_blocking(int, int)
Definition: non_blocking.c:55
#define CLOSE_ON_EXEC
Definition: iostuff.h:51
void master_sigsetup(void)
Definition: master_sig.c:226
int close_on_exec(int fd, int on)
Definition: close_on_exec.c:49
void msg_info(const char *fmt,...)
Definition: msg.c:199