diff options
author | Igor Sysoev <igor@sysoev.ru> | 2004-06-15 11:55:11 +0400 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2004-06-15 11:55:11 +0400 |
commit | 87350f269da4d82f2436aac91ae87fbd37ca6c16 (patch) | |
tree | 153b5d7d6bea91ad891de5168dd27d39e0082f66 /src | |
parent | f07f63ae46345eb2aa8a433b0bf48947d6cff95e (diff) |
nginx-0.0.7-2004-06-15-11:55:11 import
Diffstat (limited to 'src')
-rw-r--r-- | src/core/nginx.h | 2 | ||||
-rw-r--r-- | src/core/ngx_core.h | 2 | ||||
-rw-r--r-- | src/core/ngx_palloc.h | 2 | ||||
-rw-r--r-- | src/event/modules/ngx_rtsig_module.c | 23 | ||||
-rw-r--r-- | src/event/ngx_event.c | 17 | ||||
-rw-r--r-- | src/event/ngx_event.h | 2 | ||||
-rw-r--r-- | src/os/unix/ngx_posix_init.c | 9 | ||||
-rw-r--r-- | src/os/unix/ngx_process.c | 72 | ||||
-rw-r--r-- | src/os/unix/ngx_process.h | 4 | ||||
-rw-r--r-- | src/os/unix/ngx_process_cycle.c | 302 | ||||
-rw-r--r-- | src/os/unix/ngx_process_cycle.h | 21 | ||||
-rw-r--r-- | src/os/unix/ngx_socket.c | 8 |
12 files changed, 416 insertions, 48 deletions
diff --git a/src/core/nginx.h b/src/core/nginx.h index 3878ddc72..c824cdd24 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -2,7 +2,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VER "nginx/0.0.5" +#define NGINX_VER "nginx/0.0.7" #define NGINX_VAR "NGINX" #define NGX_NEWPID_EXT ".newbin" diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h index 1e194e719..55c4147f7 100644 --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -5,11 +5,11 @@ typedef struct ngx_module_s ngx_module_t; typedef struct ngx_conf_s ngx_conf_t; typedef struct ngx_cycle_s ngx_cycle_t; +typedef struct ngx_pool_s ngx_pool_t; typedef struct ngx_log_s ngx_log_t; typedef struct ngx_array_s ngx_array_t; typedef struct ngx_open_file_s ngx_open_file_t; typedef struct ngx_command_s ngx_command_t; - typedef struct ngx_file_s ngx_file_t; typedef struct ngx_event_s ngx_event_t; typedef struct ngx_connection_s ngx_connection_t; diff --git a/src/core/ngx_palloc.h b/src/core/ngx_palloc.h index 7774d356c..667bef514 100644 --- a/src/core/ngx_palloc.h +++ b/src/core/ngx_palloc.h @@ -26,8 +26,6 @@ struct ngx_pool_large_s { }; -typedef struct ngx_pool_s ngx_pool_t; - struct ngx_pool_s { char *last; char *end; diff --git a/src/event/modules/ngx_rtsig_module.c b/src/event/modules/ngx_rtsig_module.c index 4ab238888..feaf2717c 100644 --- a/src/event/modules/ngx_rtsig_module.c +++ b/src/event/modules/ngx_rtsig_module.c @@ -177,6 +177,10 @@ static ngx_int_t ngx_rtsig_add_connection(ngx_connection_t *c) ngx_rtsig_conf_t *rtscf; if (c->read->accept && c->read->disabled) { + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "rtsig enable connection: fd:%d", c->fd); + if (fcntl(c->fd, F_SETOWN, ngx_pid) == -1) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, "fcntl(F_SETOWN) failed"); @@ -233,14 +237,20 @@ static ngx_int_t ngx_rtsig_del_connection(ngx_connection_t *c, u_int flags) "rtsig del connection: fd:%d", c->fd); if ((flags & NGX_DISABLE_EVENT) && c->read->accept) { + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "rtsig disable connection: fd:%d", c->fd); + c->read->active = 0; - c->read->disabled = 0; + c->read->disabled = 1; return NGX_OK; } if (flags & NGX_CLOSE_EVENT) { c->read->active = 0; c->write->active = 0; + c->read->posted = 0; + c->write->posted = 0; return NGX_OK; } @@ -252,6 +262,8 @@ static ngx_int_t ngx_rtsig_del_connection(ngx_connection_t *c, u_int flags) c->read->active = 0; c->write->active = 0; + c->read->posted = 0; + c->write->posted = 0; return NGX_OK; } @@ -299,6 +311,8 @@ ngx_int_t ngx_rtsig_process_events(ngx_cycle_t *cycle) ngx_accept_disabled--; } else { + ngx_accept_mutex_held = 0; + if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { return NGX_ERROR; } @@ -517,7 +531,8 @@ ngx_int_t ngx_rtsig_process_events(ngx_cycle_t *cycle) static ngx_int_t ngx_rtsig_process_overflow(ngx_cycle_t *cycle) { - int name[2], len, rtsig_max, rtsig_nr, events, ready; + int name[2], rtsig_max, rtsig_nr, events, ready; + size_t len; ngx_int_t tested, n, i; ngx_err_t err; ngx_connection_t *c; @@ -709,8 +724,8 @@ static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf) ngx_conf_init_value(rtscf->signo, SIGRTMIN + 10); ngx_conf_init_value(rtscf->overflow_events, 16); - ngx_conf_init_value(rtscf->overflow_test, 100); - ngx_conf_init_value(rtscf->overflow_threshold, 4); + ngx_conf_init_value(rtscf->overflow_test, 32); + ngx_conf_init_value(rtscf->overflow_threshold, 10); return NGX_CONF_OK; } diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index 208d17117..a1153a6dd 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -628,7 +628,7 @@ static void *ngx_event_create_conf(ngx_cycle_t *cycle) static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf) { - ngx_event_conf_t *ecf = conf; + ngx_event_conf_t *ecf = conf; #if (HAVE_KQUEUE) @@ -650,6 +650,8 @@ static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf) #elif (HAVE_RTSIG) + ngx_core_conf_t *ccf; + ngx_conf_init_unsigned_value(ecf->connections, DEFAULT_CONNECTIONS); ngx_conf_init_value(ecf->use, ngx_rtsig_module.ctx_index); ngx_conf_init_ptr_value(ecf->name, ngx_rtsig_module_ctx.name->data); @@ -701,5 +703,18 @@ static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf) ngx_conf_init_value(ecf->accept_mutex, 1); ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500); +#if (HAVE_RTSIG) + if (ecf->use == ngx_rtsig_module.ctx_index && ecf->accept_mutex == 0) { + ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, + ngx_core_module); + if (ccf->worker_processes) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, + "the \"rtsig\" method requires " + "\"accept_mutex\" to be on"); + return NGX_CONF_ERROR; + } + } +#endif + return NGX_CONF_OK; } diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h index 1b9dfb290..986ae0e58 100644 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -277,11 +277,11 @@ extern ngx_event_actions_t ngx_event_actions; */ #define NGX_CLOSE_EVENT 1 +#define NGX_DISABLE_EVENT 2 /* these flags have a meaning only for kqueue */ #define NGX_LOWAT_EVENT 0 -#define NGX_DISABLE_EVENT 0 #define NGX_VNODE_EVENT 0 diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c index dc96ddd85..e2ed96a90 100644 --- a/src/os/unix/ngx_posix_init.c +++ b/src/os/unix/ngx_posix_init.c @@ -46,6 +46,8 @@ ngx_signal_t signals[] = { { SIGINT, "SIGINT", ngx_signal_handler }, + { SIGIO, "SIGIO", ngx_signal_handler }, + { SIGCHLD, "SIGCHLD", ngx_signal_handler }, { SIGPIPE, "SIGPIPE, SIG_IGN", SIG_IGN }, @@ -172,11 +174,15 @@ void ngx_signal_handler(int signo) case SIGALRM: if (!ngx_terminate) { ngx_timer = 1; - action = ", shutting down old worker process"; + action = ", shutting down old worker processes"; } break; + case SIGIO: + ngx_sigio = 1; + break; + case SIGCHLD: ngx_reap = 1; break; @@ -206,6 +212,7 @@ void ngx_signal_handler(int signo) 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; } diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c index aebf4ea36..81af78fca 100644 --- a/src/os/unix/ngx_process.c +++ b/src/os/unix/ngx_process.c @@ -6,7 +6,8 @@ static void ngx_execute_proc(ngx_cycle_t *cycle, void *data); -ngx_uint_t ngx_last_process; +ngx_int_t ngx_last_process; +ngx_socket_t ngx_channel; ngx_process_t ngx_processes[NGX_MAX_PROCESSES]; @@ -14,17 +15,44 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data, char *name, ngx_int_t respawn) { + u_long on; ngx_pid_t pid; + ngx_int_t s; - pid = fork(); + s = respawn >= 0 ? respawn : ngx_last_process; + + + /* Solaris 9 still has no AF_LOCAL */ - if (pid == -1) { + if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "fork() failed while spawning \"%s\"", name); + "socketpair() failed while spawning \"%s\"", name); + return NGX_ERROR; } + on = 1; + if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "ioctl(FIOASYNC) failed while spawning \"%s\"", name); + return NGX_ERROR; + } + + if (fcntl(ngx_processes[s].channel[0], F_SETOWN, ngx_pid) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "fcntl(F_SETOWN) failed while spawning \"%s\"", name); + return NGX_ERROR; + } + + ngx_channel = ngx_processes[s].channel[1]; + + + pid = fork(); + switch (pid) { + case -1: + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "fork() failed while spawning \"%s\"", name); return NGX_ERROR; case 0: @@ -39,37 +67,36 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0, "spawn %s: " PID_T_FMT, name, pid); + ngx_processes[s].pid = pid; + ngx_processes[s].exited = 0; + if (respawn >= 0) { - ngx_processes[respawn].pid = pid; - ngx_processes[respawn].exited = 0; return pid; } - ngx_processes[ngx_last_process].pid = pid; - ngx_processes[ngx_last_process].proc = proc; - ngx_processes[ngx_last_process].data = data; - ngx_processes[ngx_last_process].name = name; - ngx_processes[ngx_last_process].exited = 0; - ngx_processes[ngx_last_process].exiting = 0; + ngx_processes[s].proc = proc; + ngx_processes[s].data = data; + ngx_processes[s].name = name; + ngx_processes[s].exiting = 0; switch (respawn) { case NGX_PROCESS_RESPAWN: - ngx_processes[ngx_last_process].respawn = 1; - ngx_processes[ngx_last_process].just_respawn = 0; - ngx_processes[ngx_last_process].detached = 0; + ngx_processes[s].respawn = 1; + ngx_processes[s].just_respawn = 0; + ngx_processes[s].detached = 0; break; case NGX_PROCESS_JUST_RESPAWN: - ngx_processes[ngx_last_process].respawn = 1; - ngx_processes[ngx_last_process].just_respawn = 1; - ngx_processes[ngx_last_process].detached = 0; + ngx_processes[s].respawn = 1; + ngx_processes[s].just_respawn = 1; + ngx_processes[s].detached = 0; break; case NGX_PROCESS_DETACHED: - ngx_processes[ngx_last_process].respawn = 0; - ngx_processes[ngx_last_process].just_respawn = 0; - ngx_processes[ngx_last_process].detached = 1; + ngx_processes[s].respawn = 0; + ngx_processes[s].just_respawn = 0; + ngx_processes[s].detached = 1; break; } @@ -106,7 +133,8 @@ void ngx_process_get_status() char *process; ngx_pid_t pid; ngx_err_t err; - ngx_uint_t i, one; + ngx_int_t i; + ngx_uint_t one; struct timeval tv; one = 0; diff --git a/src/os/unix/ngx_process.h b/src/os/unix/ngx_process.h index 819064b93..1ce39e5f6 100644 --- a/src/os/unix/ngx_process.h +++ b/src/os/unix/ngx_process.h @@ -9,6 +9,7 @@ typedef void (*ngx_spawn_proc_pt) (ngx_cycle_t *cycle, void *data); typedef struct { ngx_pid_t pid; int status; + ngx_socket_t channel[2]; ngx_spawn_proc_pt proc; void *data; @@ -48,7 +49,8 @@ ngx_pid_t ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx); void ngx_process_get_status(void); extern ngx_pid_t ngx_pid; -extern ngx_uint_t ngx_last_process; +extern ngx_int_t ngx_last_process; +extern ngx_socket_t ngx_channel; extern ngx_process_t ngx_processes[NGX_MAX_PROCESSES]; diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c index 21b28cf9f..d30e73812 100644 --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -11,6 +11,7 @@ static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo); static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx); static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data); +static void ngx_channel_handler(ngx_event_t *ev); #if (NGX_THREADS) static int ngx_worker_thread_cycle(void *data); #endif @@ -22,6 +23,7 @@ ngx_uint_t ngx_threaded; sig_atomic_t ngx_reap; sig_atomic_t ngx_timer; +sig_atomic_t ngx_sigio; sig_atomic_t ngx_terminate; sig_atomic_t ngx_quit; ngx_uint_t ngx_exiting; @@ -45,8 +47,7 @@ void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx) char *title; u_char *p; size_t size; - ngx_int_t n; - ngx_uint_t i; + ngx_int_t n, i; sigset_t set; struct timeval tv; struct itimerval itv; @@ -57,6 +58,7 @@ void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx) sigemptyset(&set); sigaddset(&set, SIGCHLD); sigaddset(&set, SIGALRM); + sigaddset(&set, SIGIO); sigaddset(&set, SIGINT); sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL)); @@ -360,8 +362,31 @@ static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo) { - ngx_uint_t i; - ngx_err_t err; + ngx_int_t i; + ngx_err_t err; + ngx_channel_t ch; + + + switch (signo) { + + case ngx_signal_value(NGX_SHUTDOWN_SIGNAL): + ch.command = NGX_CMD_QUIT; + break; + + case ngx_signal_value(NGX_TERMINATE_SIGNAL): + ch.command = NGX_CMD_TERMINATE; + break; + + case ngx_signal_value(NGX_REOPEN_SIGNAL): + ch.command = NGX_CMD_REOPEN; + break; + + default: + ch.command = 0; + } + + ch.fd = -1; + for (i = 0; i < ngx_last_process; i++) { @@ -380,6 +405,18 @@ static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo) continue; } + if (ch.command) { + if (ngx_write_channel(ngx_processes[i].channel[0], + &ch, sizeof(ngx_channel_t), cycle->log) == NGX_OK) + { + if (signo != ngx_signal_value(NGX_REOPEN_SIGNAL)) { + ngx_processes[i].exiting = 1; + } + + continue; + } + } + ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0, "kill (" PID_T_FMT ", %d)" , ngx_processes[i].pid, signo); @@ -420,21 +457,22 @@ static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx) static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) { - sigset_t set; - ngx_uint_t i; - ngx_listening_t *ls; - ngx_core_conf_t *ccf; + sigset_t set; + ngx_int_t n; + ngx_uint_t i; + ngx_listening_t *ls; + ngx_core_conf_t *ccf; + ngx_connection_t *c; #if (NGX_THREADS) - ngx_tid_t tid; + ngx_tid_t tid; #endif ngx_process = NGX_PROCESS_WORKER; - ngx_last_process = 0; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ccf->group != (gid_t) NGX_CONF_UNSET) { - if (setuid(ccf->group) == -1) { + if (setgid(ccf->group) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setgid(%d) failed", ccf->group); /* fatal */ @@ -442,7 +480,7 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) } } - if (ccf->user != (uid_t) NGX_CONF_UNSET && geteuid() == 0) { + if (ccf->user != (uid_t) NGX_CONF_UNSET) { if (setuid(ccf->user) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, "setuid(%d) failed", ccf->user); @@ -489,6 +527,59 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) } } + for (n = 0; n < ngx_last_process; n++) { + + ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, + "close channel %d", ngx_processes[n].channel[1]); + + if (close(ngx_processes[n].channel[1]) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "close() failed"); + } + } + + if (close(ngx_processes[ngx_last_process].channel[0]) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "close() failed"); + } + +#if 0 + ngx_last_process = 0; +#endif + + c = &cycle->connections[ngx_channel]; + ngx_memzero(c, sizeof(ngx_connection_t)); + + c->fd = ngx_channel; + c->pool = cycle->pool; + c->read = &cycle->read_events[ngx_channel]; + c->write = &cycle->write_events[ngx_channel]; + + ngx_memzero(c->read, sizeof(ngx_event_t)); + ngx_memzero(c->write, sizeof(ngx_event_t)); + + c->log = cycle->log; + c->read->log = cycle->log; + c->write->log = cycle->log; + c->read->index = NGX_INVALID_INDEX; + c->write->index = NGX_INVALID_INDEX; + c->read->data = c; + c->write->data = c; + c->read->event_handler = ngx_channel_handler; + + if (ngx_add_conn) { + if (ngx_add_conn(c) == NGX_ERROR) { + /* fatal */ + exit(2); + } + + } else { + if (ngx_add_event(c->read, NGX_READ_EVENT, 0) == NGX_ERROR) { + /* fatal */ + exit(2); + } + } + ngx_setproctitle("worker process"); #if (NGX_THREADS) @@ -555,6 +646,37 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) } +static void ngx_channel_handler(ngx_event_t *ev) +{ + ngx_int_t n; + ngx_channel_t ch; + ngx_connection_t *c; + + c = ev->data; + + n = ngx_read_channel(c->fd, &ch, sizeof(ngx_channel_t), ev->log); + + if (n <= 0) { + return; + } + + switch (ch.command) { + + case NGX_CMD_QUIT: + ngx_quit = 1; + break; + + case NGX_CMD_TERMINATE: + ngx_terminate = 1; + break; + + case NGX_CMD_REOPEN: + ngx_reopen = 1; + break; + } +} + + #if (NGX_THREADS) int ngx_worker_thread_cycle(void *data) @@ -597,3 +719,159 @@ int ngx_worker_thread_cycle(void *data) } #endif + + +ngx_int_t ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, + ngx_log_t *log) +{ + ssize_t n; + ngx_err_t err; + struct iovec iov[1]; + struct msghdr msg; + struct cmsghdr cm; + +#if (HAVE_MSGHDR_MSG_CONTROL) + + if (ch->fd == -1) { + msg.msg_control = NULL; + msg.msg_controllen = 0; + + } else { + msg.msg_control = &cm; + msg.msg_controllen = sizeof(struct cmsghdr) + sizeof(int); + + cm.cmsg_len = sizeof(struct cmsghdr) + sizeof(int); + cm.cmsg_level = SOL_SOCKET; + cm.cmsg_type = SCM_RIGHTS; + *((int *) ((char *) &cm + sizeof(struct cmsghdr))) = ch->fd; + } + +#else + + if (ch->fd == -1) { + msg.msg_accrights = NULL; + msg.msg_accrightslen = 0; + + } else { + msg.msg_accrights = (caddr_t) &ch->fd; + msg.msg_accrightslen = sizeof(int); + } + +#endif + + iov[0].iov_base = (char *) ch; + iov[0].iov_len = size; + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + n = sendmsg(s, &msg, MSG_DONTWAIT); + + if (n == -1) { + err = ngx_errno; + if (err == NGX_EAGAIN) { + return NGX_AGAIN; + } + + ngx_log_error(NGX_LOG_ALERT, log, err, "sendmsg() failed"); + return NGX_ERROR; + } + + return NGX_OK; +} + + +ngx_int_t ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, + ngx_log_t *log) +{ + int fd; + ssize_t n; + ngx_err_t err; + struct iovec iov[1]; + struct msghdr msg; + struct cmsghdr *cm; + + iov[0].iov_base = (char *) ch; + iov[0].iov_len = size; + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + +#if (HAVE_MSGHDR_MSG_CONTROL) + msg.msg_control = &cm; + msg.msg_controllen = sizeof(struct cmsghdr) + sizeof(int); +#else + msg.msg_accrights = (caddr_t) &fd; + msg.msg_accrightslen = sizeof(int); +#endif + + n = recvmsg(s, &msg, MSG_DONTWAIT); + + if (n == -1) { + err = ngx_errno; + if (err == NGX_EAGAIN) { + return NGX_AGAIN; + } + + ngx_log_error(NGX_LOG_ALERT, log, err, "recvmsg() failed"); + return NGX_ERROR; + } + + if ((size_t) n < sizeof(ngx_channel_t)) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "recvmsg() returned not enough data"); + return NGX_ERROR; + } + +#if (HAVE_MSGHDR_MSG_CONTROL) + + if (ch->command == NGX_CMD_OPEN_CHANNEL) { + cm = msg.msg_control; + + if (cm == NULL) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "recvmsg() returned no ancillary data"); + return NGX_ERROR; + } + + if (cm->cmsg_len < sizeof(struct cmsghdr) + sizeof(int)) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "recvmsg() returned too small ancillary data"); + return NGX_ERROR; + } + + if (cm->cmsg_level != SOL_SOCKET || cm->cmsg_type != SCM_RIGHTS) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "recvmsg() returned invalid ancillary data " + "level %d or type %d", cm->cmsg_level, cm->cmsg_type); + return NGX_ERROR; + } + + ch->fd = *((int *) ((char *) cm + sizeof(struct cmsghdr))); + } + + if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "recvmsg() truncated data"); + } + +#else + + if (ch->command == NGX_CMD_OPEN_CHANNEL) { + if (msg.msg_accrightslen != sizeof(int)) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "recvmsg() returned no ancillary data"); + return NGX_ERROR; + } + + ch->fd = fd; + } + +#endif + + return n; +} diff --git a/src/os/unix/ngx_process_cycle.h b/src/os/unix/ngx_process_cycle.h index 056889848..a4a3e91a9 100644 --- a/src/os/unix/ngx_process_cycle.h +++ b/src/os/unix/ngx_process_cycle.h @@ -6,6 +6,20 @@ #include <ngx_core.h> +#define NGX_CMD_OPEN_CHANNEL 1 +#define NGX_CMD_CLOSE_CHANNEL 2 +#define NGX_CMD_QUIT 3 +#define NGX_CMD_TERMINATE 4 +#define NGX_CMD_REOPEN 5 + + +typedef struct { + ngx_uint_t command; + ngx_pid_t pid; + ngx_fd_t fd; +} ngx_channel_t; + + typedef struct { int argc; char *const *argv; @@ -21,6 +35,12 @@ void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx); void ngx_single_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx); +ngx_int_t ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, + ngx_log_t *log); +ngx_int_t ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, + ngx_log_t *log); + + extern ngx_uint_t ngx_process; extern ngx_pid_t ngx_pid; extern ngx_pid_t ngx_new_binary; @@ -30,6 +50,7 @@ extern ngx_uint_t ngx_exiting; extern sig_atomic_t ngx_reap; extern sig_atomic_t ngx_timer; +extern sig_atomic_t ngx_sigio; extern sig_atomic_t ngx_quit; extern sig_atomic_t ngx_terminate; extern sig_atomic_t ngx_noaccept; diff --git a/src/os/unix/ngx_socket.c b/src/os/unix/ngx_socket.c index 443c93bbf..da9ccbbd0 100644 --- a/src/os/unix/ngx_socket.c +++ b/src/os/unix/ngx_socket.c @@ -19,7 +19,9 @@ int ngx_nonblocking(ngx_socket_t s) { - unsigned long nb = 1; + u_long nb; + + nb = 1; return ioctl(s, FIONBIO, &nb); } @@ -27,7 +29,9 @@ int ngx_nonblocking(ngx_socket_t s) int ngx_blocking(ngx_socket_t s) { - unsigned long nb = 0; + u_long nb; + + nb = 0; return ioctl(s, FIONBIO, &nb); } |