root/sapi/fpm/fpm/fpm_signals.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sig_soft_quit
  2. sig_handler
  3. fpm_signals_init_main
  4. fpm_signals_init_child
  5. fpm_signals_get_fd

   1 
   2         /* $Id: fpm_signals.c,v 1.24 2008/08/26 15:09:15 anight Exp $ */
   3         /* (c) 2007,2008 Andrei Nigmatulin */
   4 
   5 #include "fpm_config.h"
   6 
   7 #include <signal.h>
   8 #include <stdio.h>
   9 #include <sys/types.h>
  10 #include <sys/socket.h>
  11 #include <stdlib.h>
  12 #include <string.h>
  13 #include <fcntl.h>
  14 #include <unistd.h>
  15 #include <errno.h>
  16 
  17 #include "fpm.h"
  18 #include "fpm_signals.h"
  19 #include "fpm_sockets.h"
  20 #include "fpm_php.h"
  21 #include "zlog.h"
  22 
  23 static int sp[2];
  24 
  25 const char *fpm_signal_names[NSIG + 1] = {
  26 #ifdef SIGHUP
  27         [SIGHUP]                = "SIGHUP",
  28 #endif
  29 #ifdef SIGINT
  30         [SIGINT]                = "SIGINT",
  31 #endif
  32 #ifdef SIGQUIT
  33         [SIGQUIT]               = "SIGQUIT",
  34 #endif
  35 #ifdef SIGILL
  36         [SIGILL]                = "SIGILL",
  37 #endif
  38 #ifdef SIGTRAP
  39         [SIGTRAP]               = "SIGTRAP",
  40 #endif
  41 #ifdef SIGABRT
  42         [SIGABRT]               = "SIGABRT",
  43 #endif
  44 #ifdef SIGEMT
  45         [SIGEMT]                = "SIGEMT",
  46 #endif
  47 #ifdef SIGBUS
  48         [SIGBUS]                = "SIGBUS",
  49 #endif
  50 #ifdef SIGFPE
  51         [SIGFPE]                = "SIGFPE",
  52 #endif
  53 #ifdef SIGKILL
  54         [SIGKILL]               = "SIGKILL",
  55 #endif
  56 #ifdef SIGUSR1
  57         [SIGUSR1]               = "SIGUSR1",
  58 #endif
  59 #ifdef SIGSEGV
  60         [SIGSEGV]               = "SIGSEGV",
  61 #endif
  62 #ifdef SIGUSR2
  63         [SIGUSR2]               = "SIGUSR2",
  64 #endif
  65 #ifdef SIGPIPE
  66         [SIGPIPE]               = "SIGPIPE",
  67 #endif
  68 #ifdef SIGALRM
  69         [SIGALRM]               = "SIGALRM",
  70 #endif
  71 #ifdef SIGTERM
  72         [SIGTERM]               = "SIGTERM",
  73 #endif
  74 #ifdef SIGCHLD
  75         [SIGCHLD]               = "SIGCHLD",
  76 #endif
  77 #ifdef SIGCONT
  78         [SIGCONT]               = "SIGCONT",
  79 #endif
  80 #ifdef SIGSTOP
  81         [SIGSTOP]               = "SIGSTOP",
  82 #endif
  83 #ifdef SIGTSTP
  84         [SIGTSTP]               = "SIGTSTP",
  85 #endif
  86 #ifdef SIGTTIN
  87         [SIGTTIN]               = "SIGTTIN",
  88 #endif
  89 #ifdef SIGTTOU
  90         [SIGTTOU]               = "SIGTTOU",
  91 #endif
  92 #ifdef SIGURG
  93         [SIGURG]                = "SIGURG",
  94 #endif
  95 #ifdef SIGXCPU
  96         [SIGXCPU]               = "SIGXCPU",
  97 #endif
  98 #ifdef SIGXFSZ
  99         [SIGXFSZ]               = "SIGXFSZ",
 100 #endif
 101 #ifdef SIGVTALRM
 102         [SIGVTALRM]     = "SIGVTALRM",
 103 #endif
 104 #ifdef SIGPROF
 105         [SIGPROF]               = "SIGPROF",
 106 #endif
 107 #ifdef SIGWINCH
 108         [SIGWINCH]              = "SIGWINCH",
 109 #endif
 110 #ifdef SIGINFO
 111         [SIGINFO]               = "SIGINFO",
 112 #endif
 113 #ifdef SIGIO
 114         [SIGIO]                 = "SIGIO",
 115 #endif
 116 #ifdef SIGPWR
 117         [SIGPWR]                = "SIGPWR",
 118 #endif
 119 #ifdef SIGSYS
 120         [SIGSYS]                = "SIGSYS",
 121 #endif
 122 #ifdef SIGWAITING
 123         [SIGWAITING]    = "SIGWAITING",
 124 #endif
 125 #ifdef SIGLWP
 126         [SIGLWP]                = "SIGLWP",
 127 #endif
 128 #ifdef SIGFREEZE
 129         [SIGFREEZE]     = "SIGFREEZE",
 130 #endif
 131 #ifdef SIGTHAW
 132         [SIGTHAW]               = "SIGTHAW",
 133 #endif
 134 #ifdef SIGCANCEL
 135         [SIGCANCEL]     = "SIGCANCEL",
 136 #endif
 137 #ifdef SIGLOST
 138         [SIGLOST]               = "SIGLOST",
 139 #endif
 140 };
 141 
 142 static void sig_soft_quit(int signo) /* {{{ */
 143 {
 144         int saved_errno = errno;
 145 
 146         /* closing fastcgi listening socket will force fcgi_accept() exit immediately */
 147         close(0);
 148         if (0 > socket(AF_UNIX, SOCK_STREAM, 0)) {
 149                 zlog(ZLOG_WARNING, "failed to create a new socket");
 150         }
 151         fpm_php_soft_quit();
 152         errno = saved_errno;
 153 }
 154 /* }}} */
 155 
 156 static void sig_handler(int signo) /* {{{ */
 157 {
 158         static const char sig_chars[NSIG + 1] = {
 159                 [SIGTERM] = 'T',
 160                 [SIGINT]  = 'I',
 161                 [SIGUSR1] = '1',
 162                 [SIGUSR2] = '2',
 163                 [SIGQUIT] = 'Q',
 164                 [SIGCHLD] = 'C'
 165         };
 166         char s;
 167         int saved_errno;
 168 
 169         if (fpm_globals.parent_pid != getpid()) {
 170                 /* prevent a signal race condition when child process
 171                         have not set up it's own signal handler yet */
 172                 return;
 173         }
 174 
 175         saved_errno = errno;
 176         s = sig_chars[signo];
 177         write(sp[1], &s, sizeof(s));
 178         errno = saved_errno;
 179 }
 180 /* }}} */
 181 
 182 int fpm_signals_init_main() /* {{{ */
 183 {
 184         struct sigaction act;
 185 
 186         if (0 > socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) {
 187                 zlog(ZLOG_SYSERROR, "failed to init signals: socketpair()");
 188                 return -1;
 189         }
 190 
 191         if (0 > fd_set_blocked(sp[0], 0) || 0 > fd_set_blocked(sp[1], 0)) {
 192                 zlog(ZLOG_SYSERROR, "failed to init signals: fd_set_blocked()");
 193                 return -1;
 194         }
 195 
 196         if (0 > fcntl(sp[0], F_SETFD, FD_CLOEXEC) || 0 > fcntl(sp[1], F_SETFD, FD_CLOEXEC)) {
 197                 zlog(ZLOG_SYSERROR, "falied to init signals: fcntl(F_SETFD, FD_CLOEXEC)");
 198                 return -1;
 199         }
 200 
 201         memset(&act, 0, sizeof(act));
 202         act.sa_handler = sig_handler;
 203         sigfillset(&act.sa_mask);
 204 
 205         if (0 > sigaction(SIGTERM,  &act, 0) ||
 206             0 > sigaction(SIGINT,   &act, 0) ||
 207             0 > sigaction(SIGUSR1,  &act, 0) ||
 208             0 > sigaction(SIGUSR2,  &act, 0) ||
 209             0 > sigaction(SIGCHLD,  &act, 0) ||
 210             0 > sigaction(SIGQUIT,  &act, 0)) {
 211 
 212                 zlog(ZLOG_SYSERROR, "failed to init signals: sigaction()");
 213                 return -1;
 214         }
 215         return 0;
 216 }
 217 /* }}} */
 218 
 219 int fpm_signals_init_child() /* {{{ */
 220 {
 221         struct sigaction act, act_dfl;
 222 
 223         memset(&act, 0, sizeof(act));
 224         memset(&act_dfl, 0, sizeof(act_dfl));
 225 
 226         act.sa_handler = &sig_soft_quit;
 227         act.sa_flags |= SA_RESTART;
 228 
 229         act_dfl.sa_handler = SIG_DFL;
 230 
 231         close(sp[0]);
 232         close(sp[1]);
 233 
 234         if (0 > sigaction(SIGTERM,  &act_dfl,  0) ||
 235             0 > sigaction(SIGINT,   &act_dfl,  0) ||
 236             0 > sigaction(SIGUSR1,  &act_dfl,  0) ||
 237             0 > sigaction(SIGUSR2,  &act_dfl,  0) ||
 238             0 > sigaction(SIGCHLD,  &act_dfl,  0) ||
 239             0 > sigaction(SIGQUIT,  &act,      0)) {
 240 
 241                 zlog(ZLOG_SYSERROR, "failed to init child signals: sigaction()");
 242                 return -1;
 243         }
 244 
 245 #ifdef ZEND_SIGNALS
 246         zend_signal_init();
 247 #endif
 248         return 0;
 249 }
 250 /* }}} */
 251 
 252 int fpm_signals_get_fd() /* {{{ */
 253 {
 254         return sp[0];
 255 }
 256 /* }}} */
 257 

/* [<][>][^][v][top][bottom][index][help] */