diff src/os/unix/ngx_process.c @ 88:e916a291e9aa NGINX_0_1_44

nginx 0.1.44 *) Feature: the IMAP/POP3 proxy supports SSL. *) Feature: the "proxy_timeout" directive of the ngx_imap_proxy_module. *) Feature: the "userid_mark" directive. *) Feature: the $remote_user variable value is determined independently of authorization use.
author Igor Sysoev <http://sysoev.ru>
date Tue, 06 Sep 2005 00:00:00 +0400
parents 5db440287648
children 45945fa8b8ba
line wrap: on
line diff
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -10,7 +10,17 @@
 #include <ngx_channel.h>
 
 
+typedef struct {
+     int     signo;
+     char   *signame;
+     void  (*handler)(int signo);
+} ngx_signal_t;
+
+
+
 static void ngx_execute_proc(ngx_cycle_t *cycle, void *data);
+static void ngx_signal_handler(int signo);
+static void ngx_process_get_status(void);
 
 
 int              ngx_argc;
@@ -23,6 +33,45 @@ ngx_int_t        ngx_last_process;
 ngx_process_t    ngx_processes[NGX_MAX_PROCESSES];
 
 
+ngx_signal_t  signals[] = {
+    { ngx_signal_value(NGX_RECONFIGURE_SIGNAL),
+      "SIG" ngx_value(NGX_RECONFIGURE_SIGNAL),
+      ngx_signal_handler },
+
+    { ngx_signal_value(NGX_REOPEN_SIGNAL),
+      "SIG" ngx_value(NGX_REOPEN_SIGNAL),
+      ngx_signal_handler },
+
+    { ngx_signal_value(NGX_NOACCEPT_SIGNAL),
+      "SIG" ngx_value(NGX_NOACCEPT_SIGNAL),
+      ngx_signal_handler },
+
+    { ngx_signal_value(NGX_TERMINATE_SIGNAL),
+      "SIG" ngx_value(NGX_TERMINATE_SIGNAL),
+      ngx_signal_handler },
+
+    { ngx_signal_value(NGX_SHUTDOWN_SIGNAL),
+      "SIG" ngx_value(NGX_SHUTDOWN_SIGNAL),
+      ngx_signal_handler },
+
+    { ngx_signal_value(NGX_CHANGEBIN_SIGNAL),
+      "SIG" ngx_value(NGX_CHANGEBIN_SIGNAL),
+      ngx_signal_handler },
+
+    { SIGALRM, "SIGALRM", ngx_signal_handler },
+
+    { SIGINT, "SIGINT", ngx_signal_handler },
+
+    { SIGIO, "SIGIO", ngx_signal_handler },
+
+    { SIGCHLD, "SIGCHLD", ngx_signal_handler },
+
+    { SIGPIPE, "SIGPIPE, SIG_IGN", SIG_IGN },
+
+    { 0, NULL, NULL }
+};
+
+
 ngx_pid_t
 ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,
     char *name, ngx_int_t respawn)
@@ -208,7 +257,171 @@ ngx_execute_proc(ngx_cycle_t *cycle, voi
 }
 
 
+ngx_int_t
+ngx_init_signals(ngx_log_t *log)
+{
+    ngx_signal_t      *sig;
+    struct sigaction   sa;
+
+    for (sig = signals; sig->signo != 0; sig++) {
+        ngx_memzero(&sa, sizeof(struct sigaction));
+        sa.sa_handler = sig->handler;
+        sigemptyset(&sa.sa_mask);
+        if (sigaction(sig->signo, &sa, NULL) == -1) {
+            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+                          "sigaction(%s) failed", sig->signame);
+            return NGX_ERROR;
+        }
+    }
+
+    return NGX_OK;
+}
+
+
 void
+ngx_signal_handler(int signo)
+{
+    char            *action;
+    struct timeval   tv;
+    ngx_int_t        ignore;
+    ngx_err_t        err;
+    ngx_signal_t    *sig;
+
+    ignore = 0;
+
+    err = ngx_errno;
+
+    for (sig = signals; sig->signo != 0; sig++) {
+        if (sig->signo == signo) {
+            break;
+        }
+    }
+
+    ngx_gettimeofday(&tv);
+    ngx_time_update(tv.tv_sec);
+
+    action = "";
+
+    switch (ngx_process) {
+
+    case NGX_PROCESS_MASTER:
+    case NGX_PROCESS_SINGLE:
+        switch (signo) {
+
+        case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
+            ngx_quit = 1;
+            action = ", shutting down";
+            break;
+
+        case ngx_signal_value(NGX_TERMINATE_SIGNAL):
+        case SIGINT:
+            ngx_terminate = 1;
+            action = ", exiting";
+            break;
+
+        case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
+            ngx_noaccept = 1;
+            action = ", stop accepting connections";
+            break;
+
+        case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
+            ngx_reconfigure = 1;
+            action = ", reconfiguring";
+            break;
+
+        case ngx_signal_value(NGX_REOPEN_SIGNAL):
+            ngx_reopen = 1;
+            action = ", reopening logs";
+            break;
+
+        case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
+            if (getppid() > 1 || ngx_new_binary > 0) {
+
+                /*
+                 * Ignore the signal in the new binary if its parent is
+                 * not the init process, i.e. the old binary's process
+                 * is still running.  Or ingore the signal in the old binary's
+                 * process if the new binary's process is already running.
+                 */
+
+                action = ", ignoring";
+                ignore = 1;
+                break;
+            }
+
+            ngx_change_binary = 1;
+            action = ", changing binary";
+            break;
+
+        case SIGALRM:
+            if (!ngx_terminate) {
+                ngx_timer = 1;
+                action = ", shutting down old worker processes";
+            }
+
+            break;
+
+        case SIGIO:
+            ngx_sigio = 1;
+            break;
+
+        case SIGCHLD:
+            ngx_reap = 1;
+            break;
+        }
+
+        break;
+
+    case NGX_PROCESS_WORKER:
+        switch (signo) {
+
+        case ngx_signal_value(NGX_NOACCEPT_SIGNAL):
+            ngx_debug_quit = 1;
+        case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
+            ngx_quit = 1;
+            action = ", shutting down";
+            break;
+
+        case ngx_signal_value(NGX_TERMINATE_SIGNAL):
+        case SIGINT:
+            ngx_terminate = 1;
+            action = ", exiting";
+            break;
+
+        case ngx_signal_value(NGX_REOPEN_SIGNAL):
+            ngx_reopen = 1;
+            action = ", reopening logs";
+            break;
+
+        case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
+        case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
+        case SIGIO:
+            action = ", ignoring";
+            break;
+        }
+
+        break;
+    }
+
+    ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
+                  "signal %d (%s) received%s", signo, sig->signame, action);
+
+    if (ignore) {
+        ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, 0,
+                      "the changing binary signal is ignored: "
+                      "you should shutdown or terminate "
+                      "before either old or new binary's process");
+    }
+
+    if (signo == SIGCHLD) {
+        ngx_process_get_status();
+    }
+
+    ngx_set_errno(err);
+}
+
+
+static void
 ngx_process_get_status(void)
 {
     int              status;