diff --git a/src/os/unix/ngx_channel.c b/src/os/unix/ngx_channel.c index 1efa0667c..b03bbbb15 100644 --- a/src/os/unix/ngx_channel.c +++ b/src/os/unix/ngx_channel.c @@ -134,6 +134,13 @@ ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, ngx_log_t *log) } ngx_log_error(NGX_LOG_ALERT, log, err, "recvmsg() failed"); + + if (err == NGX_EMSGSIZE || err == NGX_EMFILE) { + /* file descriptor table is full */ + ngx_memzero(ch, size); + return 0; + } + return NGX_ERROR; } @@ -152,27 +159,29 @@ ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, ngx_log_t *log) if (ch->command == NGX_CMD_OPEN_CHANNEL) { - if (cmsg.cm.cmsg_len < (socklen_t) CMSG_LEN(sizeof(int))) { + if (msg.msg_controllen < (socklen_t) CMSG_LEN(sizeof(int))) { ngx_log_error(NGX_LOG_ALERT, log, 0, "recvmsg() returned too small ancillary data"); - return NGX_ERROR; - } + ch->fd = -1; - if (cmsg.cm.cmsg_level != SOL_SOCKET || cmsg.cm.cmsg_type != SCM_RIGHTS) + } else 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; + + } else { + + /* ch->fd = *(int *) CMSG_DATA(&cmsg.cm); */ + + ngx_memcpy(&ch->fd, CMSG_DATA(&cmsg.cm), sizeof(int)); } - - /* ch->fd = *(int *) CMSG_DATA(&cmsg.cm); */ - - ngx_memcpy(&ch->fd, CMSG_DATA(&cmsg.cm), sizeof(int)); } - if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) { + if (msg.msg_flags & MSG_TRUNC) { ngx_log_error(NGX_LOG_ALERT, log, 0, "recvmsg() truncated data"); } @@ -183,10 +192,11 @@ ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, ngx_log_t *log) if (msg.msg_accrightslen != sizeof(int)) { ngx_log_error(NGX_LOG_ALERT, log, 0, "recvmsg() returned no ancillary data"); - return NGX_ERROR; - } + ch->fd = -1; - ch->fd = fd; + } else { + ch->fd = fd; + } } #endif diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c index 5bc5ce979..33c25487b 100644 --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -1073,6 +1073,12 @@ ngx_channel_handler(ngx_event_t *ev) ch.slot, ch.pid, ngx_processes[ch.slot].pid, ngx_processes[ch.slot].channel[0]); + if (ngx_processes[ch.slot].channel[0] == -1 + || ngx_processes[ch.slot].pid != ch.pid) + { + break; + } + if (close(ngx_processes[ch.slot].channel[0]) == -1) { ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "close() channel failed");