diff options
author | Igor Sysoev <igor@sysoev.ru> | 2005-09-06 16:09:32 +0000 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2005-09-06 16:09:32 +0000 |
commit | ceb992921cee6f76d1752af2d388ee6a1d71e078 (patch) | |
tree | 2b4916a12d02210134939b7fb388a270e76002fa /src/os/unix/ngx_process.c | |
parent | 5650106a09de8e8d876ed38fbff57b2161d910c4 (diff) | |
download | nginx-ceb992921cee6f76d1752af2d388ee6a1d71e078.tar.gz nginx-ceb992921cee6f76d1752af2d388ee6a1d71e078.zip |
nginx-0.1.44-RELEASE importrelease-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.
Diffstat (limited to 'src/os/unix/ngx_process.c')
-rw-r--r-- | src/os/unix/ngx_process.c | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c index f9689c9af..eaf7ae4fd 100644 --- 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, void *data) } +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; |