Mercurial > hg > nginx-mail
diff src/os/unix/ngx_posix_init.c @ 0:f0b350454894 NGINX_0_1_0
nginx 0.1.0
*) The first public version.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 04 Oct 2004 00:00:00 +0400 |
parents | |
children | 4b2dafa26fe2 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/src/os/unix/ngx_posix_init.c @@ -0,0 +1,299 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#include <ngx_config.h> +#include <ngx_core.h> + + +ngx_int_t ngx_ncpu; +ngx_int_t ngx_max_sockets; +ngx_int_t ngx_inherited_nonblocking; + + +struct rlimit rlmt; + + +#if (NGX_POSIX_IO) + +ngx_os_io_t ngx_os_io = { + ngx_unix_recv, + ngx_readv_chain, + NULL, + ngx_writev_chain, + 0 +}; + + +int ngx_os_init(ngx_log_t *log) +{ + return ngx_posix_init(log); +} + + +#endif + + +void ngx_signal_handler(int signo); + + +typedef struct { + int signo; + char *signame; + void (*handler)(int signo); +} ngx_signal_t; + + +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_int_t ngx_posix_init(ngx_log_t *log) +{ + ngx_signal_t *sig; + struct sigaction sa; + + ngx_pagesize = getpagesize(); + + if (ngx_ncpu == 0) { + ngx_ncpu = 1; + } + + 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; + } + } + + if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, + "getrlimit(RLIMIT_NOFILE) failed)"); + return NGX_ERROR; + } + + ngx_max_sockets = rlmt.rlim_cur; + +#if (HAVE_INHERITED_NONBLOCK) + ngx_inherited_nonblocking = 1; +#else + ngx_inherited_nonblocking = 0; +#endif + + return NGX_OK; +} + + +void ngx_posix_status(ngx_log_t *log) +{ + ngx_log_error(NGX_LOG_INFO, log, 0, + "getrlimit(RLIMIT_NOFILE): " RLIM_T_FMT ":" RLIM_T_FMT, + rlmt.rlim_cur, rlmt.rlim_max); +} + + +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 the 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 = ", reopen 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_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 = ", reopen logs"; + break; + + case ngx_signal_value(NGX_RECONFIGURE_SIGNAL): + case ngx_signal_value(NGX_NOACCEPT_SIGNAL): + case ngx_signal_value(NGX_CHANGEBIN_SIGNAL): + case SIGIO: + action = ", ignoring"; + break; + } + + break; + } + + ngx_log_error(NGX_LOG_INFO, 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); +} + + +int ngx_posix_post_conf_init(ngx_log_t *log) +{ + ngx_fd_t pp[2]; + + if (pipe(pp) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "pipe() failed"); + return NGX_ERROR; + } + + if (dup2(pp[1], STDERR_FILENO) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDERR) failed"); + return NGX_ERROR; + } + + if (pp[1] > STDERR_FILENO) { + if (close(pp[1]) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, errno, "close() failed"); + return NGX_ERROR; + } + } + + return NGX_OK; +}