}
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;
}
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;
- }
- /* ch->fd = *(int *) CMSG_DATA(&cmsg.cm); */
+ } else {
- 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");
}
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
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");