3 * Copyright (C) Igor Sysoev
7 #include <ngx_config.h>
9 #include <ngx_channel.h>
13 ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
21 #if (NGX_HAVE_MSGHDR_MSG_CONTROL)
25 char space[CMSG_SPACE(sizeof(int))];
29 msg.msg_control = NULL;
30 msg.msg_controllen = 0;
33 msg.msg_control = (caddr_t) &cmsg;
34 msg.msg_controllen = sizeof(cmsg);
36 cmsg.cm.cmsg_len = CMSG_LEN(sizeof(int));
37 cmsg.cm.cmsg_level = SOL_SOCKET;
38 cmsg.cm.cmsg_type = SCM_RIGHTS;
39 *(int *) CMSG_DATA(&cmsg.cm) = ch->fd;
47 msg.msg_accrights = NULL;
48 msg.msg_accrightslen = 0;
51 msg.msg_accrights = (caddr_t) &ch->fd;
52 msg.msg_accrightslen = sizeof(int);
57 iov[0].iov_base = (char *) ch;
58 iov[0].iov_len = size;
65 n = sendmsg(s, &msg, 0);
69 if (err == NGX_EAGAIN) {
73 ngx_log_error(NGX_LOG_ALERT, log, err, "sendmsg() failed");
82 ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, ngx_log_t *log)
89 #if (NGX_HAVE_MSGHDR_MSG_CONTROL)
92 char space[CMSG_SPACE(sizeof(int))];
98 iov[0].iov_base = (char *) ch;
99 iov[0].iov_len = size;
106 #if (NGX_HAVE_MSGHDR_MSG_CONTROL)
107 msg.msg_control = (caddr_t) &cmsg;
108 msg.msg_controllen = sizeof(cmsg);
110 msg.msg_accrights = (caddr_t) &fd;
111 msg.msg_accrightslen = sizeof(int);
114 n = recvmsg(s, &msg, 0);
118 if (err == NGX_EAGAIN) {
122 ngx_log_error(NGX_LOG_ALERT, log, err, "recvmsg() failed");
127 ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "recvmsg() returned zero");
131 if ((size_t) n < sizeof(ngx_channel_t)) {
132 ngx_log_error(NGX_LOG_ALERT, log, 0,
133 "recvmsg() returned not enough data: %uz", n);
137 #if (NGX_HAVE_MSGHDR_MSG_CONTROL)
139 if (ch->command == NGX_CMD_OPEN_CHANNEL) {
141 if (cmsg.cm.cmsg_len < (socklen_t) CMSG_LEN(sizeof(int))) {
142 ngx_log_error(NGX_LOG_ALERT, log, 0,
143 "recvmsg() returned too small ancillary data");
147 if (cmsg.cm.cmsg_level != SOL_SOCKET || cmsg.cm.cmsg_type != SCM_RIGHTS)
149 ngx_log_error(NGX_LOG_ALERT, log, 0,
150 "recvmsg() returned invalid ancillary data "
151 "level %d or type %d",
152 cmsg.cm.cmsg_level, cmsg.cm.cmsg_type);
156 ch->fd = *(int *) CMSG_DATA(&cmsg.cm);
159 if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) {
160 ngx_log_error(NGX_LOG_ALERT, log, 0,
161 "recvmsg() truncated data");
166 if (ch->command == NGX_CMD_OPEN_CHANNEL) {
167 if (msg.msg_accrightslen != sizeof(int)) {
168 ngx_log_error(NGX_LOG_ALERT, log, 0,
169 "recvmsg() returned no ancillary data");
183 ngx_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd, ngx_int_t event,
184 ngx_event_handler_pt handler)
186 ngx_event_t *ev, *rev, *wev;
189 c = ngx_get_connection(fd, cycle->log);
195 c->pool = cycle->pool;
200 rev->log = cycle->log;
201 wev->log = cycle->log;
204 rev->lock = &c->lock;
205 wev->lock = &c->lock;
206 rev->own_lock = &c->lock;
207 wev->own_lock = &c->lock;
213 ev = (event == NGX_READ_EVENT) ? rev : wev;
215 ev->handler = handler;
217 if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
218 if (ngx_add_conn(c) == NGX_ERROR) {
219 ngx_free_connection(c);
224 if (ngx_add_event(ev, event, 0) == NGX_ERROR) {
225 ngx_free_connection(c);
235 ngx_close_channel(ngx_fd_t *fd, ngx_log_t *log)
237 if (close(fd[0]) == -1) {
238 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "close() channel failed");
241 if (close(fd[1]) == -1) {
242 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "close() channel failed");