diff --git a/auto/sources b/auto/sources index fea74c22e..e402b1c2b 100644 --- a/auto/sources +++ b/auto/sources @@ -105,6 +105,7 @@ UNIX_DEPS="$CORE_DEPS $EVENT_DEPS \ src/os/unix/ngx_errno.h \ src/os/unix/ngx_alloc.h \ src/os/unix/ngx_files.h \ + src/os/unix/ngx_channel.h \ src/os/unix/ngx_shared.h \ src/os/unix/ngx_process.h \ src/os/unix/ngx_thread.h \ @@ -121,6 +122,7 @@ UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \ src/os/unix/ngx_recv.c \ src/os/unix/ngx_readv_chain.c \ src/os/unix/ngx_writev_chain.c \ + src/os/unix/ngx_channel.c \ src/os/unix/ngx_shared.c \ src/os/unix/ngx_process.c \ src/os/unix/ngx_daemon.c \ diff --git a/src/core/nginx.c b/src/core/nginx.c index cef343418..f657efbc4 100644 --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -72,8 +72,6 @@ ngx_module_t ngx_core_module = { ngx_uint_t ngx_max_module; -ngx_uint_t ngx_inherited; - int main(int argc, char *const *argv) { @@ -162,6 +160,9 @@ int main(int argc, char *const *argv) #if (WIN32) #if 0 + + TODO: + if (ccf->run_as_service) { if (ngx_service(cycle->log) == NGX_ERROR) { return 1; @@ -177,6 +178,8 @@ int main(int argc, char *const *argv) if (ngx_daemon(cycle->log) == NGX_ERROR) { return 1; } + + ngx_daemonized = 1; } if (ngx_create_pidfile(cycle, NULL) == NGX_ERROR) { diff --git a/src/os/unix/ngx_channel.c b/src/os/unix/ngx_channel.c new file mode 100644 index 000000000..ff0aeccb0 --- /dev/null +++ b/src/os/unix/ngx_channel.c @@ -0,0 +1,213 @@ + +#include +#include +#include + + +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; + +#if (HAVE_MSGHDR_MSG_CONTROL) + + union { + struct cmsghdr cm; + char space[CMSG_SPACE(sizeof(int))]; + } cmsg; + + if (ch->fd == -1) { + msg.msg_control = NULL; + msg.msg_controllen = 0; + + } else { + msg.msg_control = (caddr_t) &cmsg; + msg.msg_controllen = sizeof(cmsg); + + cmsg.cm.cmsg_len = sizeof(cmsg); + cmsg.cm.cmsg_level = SOL_SOCKET; + cmsg.cm.cmsg_type = SCM_RIGHTS; + *(int *) CMSG_DATA(&cmsg.cm) = 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, 0); + + 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) +{ + ssize_t n; + ngx_err_t err; + struct iovec iov[1]; + struct msghdr msg; + +#if (HAVE_MSGHDR_MSG_CONTROL) + union { + struct cmsghdr cm; + char space[CMSG_SPACE(sizeof(int))]; + } cmsg; +#else + int fd; +#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; + +#if (HAVE_MSGHDR_MSG_CONTROL) + msg.msg_control = (caddr_t) &cmsg; + msg.msg_controllen = sizeof(cmsg); +#else + msg.msg_accrights = (caddr_t) &fd; + msg.msg_accrightslen = sizeof(int); +#endif + + n = recvmsg(s, &msg, 0); + + 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) { + + if (cmsg.cm.cmsg_len < sizeof(cmsg)) { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "recvmsg() returned too small ancillary data"); + return NGX_ERROR; + } + + if (cmsg.cm.cmsg_level != SOL_SOCKET || cmsg.cm.cmsg_type != SCM_RIGHTS) + { + ngx_log_error(NGX_LOG_ALERT, log, 0, + "recvmsg() returned invalid ancillary data " + "level %d or type %d", + cmsg.cm.cmsg_level, cmsg.cm.cmsg_type); + return NGX_ERROR; + } + + ch->fd = *(int *) CMSG_DATA(&cmsg.cm); + } + + 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; +} + + +ngx_int_t ngx_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd, + ngx_int_t event, ngx_event_handler_pt handler) +{ + ngx_event_t *ev, *rev, *wev; + ngx_connection_t *c; + + c = &cycle->connections[fd]; + rev = &cycle->read_events[fd]; + wev = &cycle->write_events[fd]; + + ngx_memzero(c, sizeof(ngx_connection_t)); + ngx_memzero(rev, sizeof(ngx_event_t)); + ngx_memzero(wev, sizeof(ngx_event_t)); + + c->fd = fd; + c->pool = cycle->pool; + + c->read = rev; + c->write = wev; + + c->log = cycle->log; + rev->log = cycle->log; + wev->log = cycle->log; + rev->index = NGX_INVALID_INDEX; + wev->index = NGX_INVALID_INDEX; + rev->data = c; + wev->data = c; + + ev = (event == NGX_READ_EVENT) ? rev : wev; + + ev->event_handler = handler; + + if (ngx_add_conn) { + if (ngx_add_conn(c) == NGX_ERROR) { + return NGX_ERROR; + } + + } else { + if (ngx_add_event(ev, event, 0) == NGX_ERROR) { + return NGX_ERROR; + } + } + + return NGX_OK; +} diff --git a/src/os/unix/ngx_channel.h b/src/os/unix/ngx_channel.h new file mode 100644 index 000000000..ffa2ed4c8 --- /dev/null +++ b/src/os/unix/ngx_channel.h @@ -0,0 +1,26 @@ +#ifndef _NGX_CHANNEL_H_INCLUDED_ +#define _NGX_CHANNEL_H_INCLUDED_ + + +#include +#include +#include + + +typedef struct { + ngx_uint_t command; + ngx_pid_t pid; + ngx_int_t slot; + ngx_fd_t fd; +} ngx_channel_t; + + +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); +ngx_int_t ngx_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd, + ngx_int_t event, ngx_event_handler_pt handler); + + +#endif /* _NGX_CHANNEL_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c index 799eabee3..d6e2d390d 100644 --- a/src/os/unix/ngx_process.c +++ b/src/os/unix/ngx_process.c @@ -65,6 +65,22 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, return NGX_ERROR; } + if (fcntl(ngx_processes[s].channel[0], F_SETFD, FD_CLOEXEC) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "fcntl(FD_CLOEXEC) failed while spawning \"%s\"", + name); + ngx_close_channel(ngx_processes[s].channel, cycle->log); + return NGX_ERROR; + } + + if (fcntl(ngx_processes[s].channel[1], F_SETFD, FD_CLOEXEC) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "fcntl(FD_CLOEXEC) failed while spawning \"%s\"", + name); + ngx_close_channel(ngx_processes[s].channel, cycle->log); + return NGX_ERROR; + } + ngx_channel = ngx_processes[s].channel[1]; } else { diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c index 547f88ca1..21966f272 100644 --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -2,8 +2,7 @@ #include #include #include - -#include +#include static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, @@ -34,6 +33,7 @@ sig_atomic_t ngx_reopen; sig_atomic_t ngx_change_binary; ngx_pid_t ngx_new_binary; ngx_uint_t ngx_inherited; +ngx_uint_t ngx_daemonized; sig_atomic_t ngx_noaccept; ngx_uint_t ngx_noaccepting; @@ -609,37 +609,11 @@ static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) 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); - } + if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT, + ngx_channel_handler) == NGX_ERROR) + { + /* fatal */ + exit(2); } ngx_setproctitle("worker process"); @@ -813,165 +787,3 @@ 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; - -#if (HAVE_MSGHDR_MSG_CONTROL) - - union { - struct cmsghdr cm; - char space[CMSG_SPACE(sizeof(int))]; - } cmsg; - - if (ch->fd == -1) { - msg.msg_control = NULL; - msg.msg_controllen = 0; - - } else { - msg.msg_control = (caddr_t) &cmsg; - msg.msg_controllen = sizeof(cmsg); - - cmsg.cm.cmsg_len = sizeof(cmsg); - cmsg.cm.cmsg_level = SOL_SOCKET; - cmsg.cm.cmsg_type = SCM_RIGHTS; - *(int *) CMSG_DATA(&cmsg.cm) = 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, 0); - - 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) -{ - ssize_t n; - ngx_err_t err; - struct iovec iov[1]; - struct msghdr msg; - -#if (HAVE_MSGHDR_MSG_CONTROL) - union { - struct cmsghdr cm; - char space[CMSG_SPACE(sizeof(int))]; - } cmsg; -#else - int fd; -#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; - -#if (HAVE_MSGHDR_MSG_CONTROL) - msg.msg_control = (caddr_t) &cmsg; - msg.msg_controllen = sizeof(cmsg); -#else - msg.msg_accrights = (caddr_t) &fd; - msg.msg_accrightslen = sizeof(int); -#endif - - n = recvmsg(s, &msg, 0); - - 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) { - - if (cmsg.cm.cmsg_len < sizeof(cmsg)) { - ngx_log_error(NGX_LOG_ALERT, log, 0, - "recvmsg() returned too small ancillary data"); - return NGX_ERROR; - } - - if (cmsg.cm.cmsg_level != SOL_SOCKET || cmsg.cm.cmsg_type != SCM_RIGHTS) - { - ngx_log_error(NGX_LOG_ALERT, log, 0, - "recvmsg() returned invalid ancillary data " - "level %d or type %d", - cmsg.cm.cmsg_level, cmsg.cm.cmsg_type); - return NGX_ERROR; - } - - ch->fd = *(int *) CMSG_DATA(&cmsg.cm); - } - - 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 7d0053afc..b0a7d62bc 100644 --- a/src/os/unix/ngx_process_cycle.h +++ b/src/os/unix/ngx_process_cycle.h @@ -13,14 +13,6 @@ #define NGX_CMD_REOPEN 5 -typedef struct { - ngx_uint_t command; - ngx_pid_t pid; - ngx_int_t slot; - ngx_fd_t fd; -} ngx_channel_t; - - typedef struct { int argc; char *const *argv; @@ -36,16 +28,11 @@ 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; extern ngx_uint_t ngx_inherited; +extern ngx_uint_t ngx_daemonized; extern ngx_uint_t ngx_threaded; extern ngx_uint_t ngx_exiting;