您的位置:首页 > 其它

4.1.3.2 master_sigsetup函数:信号处理程序初始化

2016-04-07 10:31 323 查看
501行的/master/master_sig.c/master_sigsetup函数初始化信号处理程序。

master模块对信号处理的大致方式是:

1 对SIGINT, SIGQUIT, SIGILL, SIGBUS, SIGSEGV, SIGTERM信号杀死进程。

2 对SIGHUP信号重新读取master.cf配置文件。守护进程经常利用这个信号重读配置文件。该进程表示终端断开,但守护进程不会使用到标准输入输出,所以可以重定义该信号来执行重读配置文件的功能。

3 对SIGCHLD信号回收子进程信息(子进程已死亡)。

4 子进程通过master_sig_pipe管道报告SIGHUP信号和SIGCHLD信号。

/master/master_sig.c
215 /* master_sigsetup - set up signalhandlers */
216
217 void   master_sigsetup(void)
218 {
219    const char *myname = "master_sigsetup";
220    struct sigaction action;
221    static int sigs[] = {
222        SIGINT, SIGQUIT, SIGILL, SIGBUS, SIGSEGV, SIGTERM,
223    };
224    unsigned i;
225
226    sigemptyset(&action.sa_mask);
227    action.sa_flags = 0;
228
229    /*
230     * Prepare to kill our children when we receive any of the above signals.
231     */
232    action.sa_handler = master_sigdeath;
233    for (i = 0; i < sizeof(sigs) / sizeof(sigs[0]); i++)
234        if (sigaction(sigs[i], &action, (struct sigaction *) 0) < 0)
235             msg_fatal("%s: sigaction(%d):%m", myname, sigs[i]);
236
237 #ifdef USE_SIG_PIPE
238    if (pipe(master_sig_pipe))
239        msg_fatal("pipe: %m");
240    non_blocking(SIG_PIPE_WRITE_FD, NON_BLOCKING);
241    non_blocking(SIG_PIPE_READ_FD, NON_BLOCKING);
242    close_on_exec(SIG_PIPE_WRITE_FD, CLOSE_ON_EXEC);
243    close_on_exec(SIG_PIPE_READ_FD, CLOSE_ON_EXEC);
244    event_enable_read(SIG_PIPE_READ_FD, master_sig_event, (void *) 0);
245 #endif
246
247    /*
248     * Intercept SIGHUP (re-read config file) and SIGCHLD (child exit).
249     */
250 #ifdef SA_RESTART
251    action.sa_flags |= SA_RESTART;
252 #endif
253    action.sa_handler = master_sighup;
254    if (sigaction(SIGHUP, &action, (struct sigaction *) 0) < 0)
255        msg_fatal("%s: sigaction(%d): %m", myname, SIGHUP);
256
257    action.sa_flags |= SA_NOCLDSTOP;
258    action.sa_handler = master_sigchld;
259    if (sigaction(SIGCHLD, &action, (struct sigaction *) 0) < 0)
260        msg_fatal("%s: sigaction(%d): %m", myname, SIGCHLD);
261 }


221-235 对收到SIGINT(终端中断,如按下ctrl+c)、 SIGQUIT(终端退出)、SIGILL(非法硬件指令)、 SIGBUS(硬件故障)、 SIGSEGV(无效存储访问)、SIGTERM(终止)这几个信号的模块设定信号处理函数master_sigdeath,该函数执行kill杀死进程。

237-245 设置信号读写管道及事件回调函数,该段代码只要系统不是HPUX9、HPUX10、HPUX11系统均会被执行:

/master/master_sig.c
#ifdef USE_SIG_RETURN
#include <sys/syscall.h>
#undef USE_SIG_PIPE
#else
#define USE_SIG_PIPE
#endif

/util/sys_defs.h
#ifdef HPUX11
#ifdef HPUX10
#ifdef HPUX9
#define USE_SIG_RETURN


回调函数为master_sig_event,负责读管道:

/master/master_sig.c
158 /* master_sig_event - called uponreturn from select() */
159
160 static void master_sig_event(intunused_event, void *unused_context)
161 {
162    char    c[1];
163
164    while (read(SIG_PIPE_READ_FD, c, 1) > 0)
165         /* void */ ;
166 }


254-260 设置SIGHUP信号和SIGCHLD信号处理函数为master_sighup和master_sigchld,这两个函数仅仅进行写管道操作.

对SIGHUP信号和SIGCHLD信号设置信号处理函数master_sighup和master_sigchld,这两个信号处理函数所做的仅仅是写信号处理所用的管道,真正的操作在master.c中进行:

/master/master_sig.c
118 /* master_sighup - register arrival ofhangup 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'tput
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 fromselect() */
139
140 static void master_sigchld(intunused_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'tput
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 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: