~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/os/unix/ngx_channel.c

Version: ~ [ nginx-0.8.20 ] ~ [ nginx-0.7.62 ] ~ [ nginx-0.6.39 ] ~

  1 
  2 /*
  3  * Copyright (C) Igor Sysoev
  4  */
  5 
  6 
  7 #include <ngx_config.h>
  8 #include <ngx_core.h>
  9 #include <ngx_channel.h>
 10 
 11 
 12 ngx_int_t
 13 ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
 14     ngx_log_t *log)
 15 {
 16     ssize_t             n;
 17     ngx_err_t           err;
 18     struct iovec        iov[1];
 19     struct msghdr       msg;
 20 
 21 #if (NGX_HAVE_MSGHDR_MSG_CONTROL)
 22 
 23     union {
 24         struct cmsghdr  cm;
 25         char            space[CMSG_SPACE(sizeof(int))];
 26     } cmsg;
 27 
 28     if (ch->fd == -1) {
 29         msg.msg_control = NULL;
 30         msg.msg_controllen = 0;
 31 
 32     } else {
 33         msg.msg_control = (caddr_t) &cmsg;
 34         msg.msg_controllen = sizeof(cmsg);
 35 
 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;
 40     }
 41 
 42     msg.msg_flags = 0;
 43 
 44 #else
 45 
 46     if (ch->fd == -1) {
 47         msg.msg_accrights = NULL;
 48         msg.msg_accrightslen = 0;
 49 
 50     } else {
 51         msg.msg_accrights = (caddr_t) &ch->fd;
 52         msg.msg_accrightslen = sizeof(int);
 53     }
 54 
 55 #endif
 56 
 57     iov[0].iov_base = (char *) ch;
 58     iov[0].iov_len = size;
 59 
 60     msg.msg_name = NULL;
 61     msg.msg_namelen = 0;
 62     msg.msg_iov = iov;
 63     msg.msg_iovlen = 1;
 64 
 65     n = sendmsg(s, &msg, 0);
 66 
 67     if (n == -1) {
 68         err = ngx_errno;
 69         if (err == NGX_EAGAIN) {
 70             return NGX_AGAIN;
 71         }
 72 
 73         ngx_log_error(NGX_LOG_ALERT, log, err, "sendmsg() failed");
 74         return NGX_ERROR;
 75     }
 76 
 77     return NGX_OK;
 78 }
 79 
 80 
 81 ngx_int_t
 82 ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, ngx_log_t *log)
 83 {
 84     ssize_t             n;
 85     ngx_err_t           err;
 86     struct iovec        iov[1];
 87     struct msghdr       msg;
 88 
 89 #if (NGX_HAVE_MSGHDR_MSG_CONTROL)
 90     union {
 91         struct cmsghdr  cm;
 92         char            space[CMSG_SPACE(sizeof(int))];
 93     } cmsg;
 94 #else
 95     int                 fd;
 96 #endif
 97 
 98     iov[0].iov_base = (char *) ch;
 99     iov[0].iov_len = size;
100 
101     msg.msg_name = NULL;
102     msg.msg_namelen = 0;
103     msg.msg_iov = iov;
104     msg.msg_iovlen = 1;
105 
106 #if (NGX_HAVE_MSGHDR_MSG_CONTROL)
107     msg.msg_control = (caddr_t) &cmsg;
108     msg.msg_controllen = sizeof(cmsg);
109 #else
110     msg.msg_accrights = (caddr_t) &fd;
111     msg.msg_accrightslen = sizeof(int);
112 #endif
113 
114     n = recvmsg(s, &msg, 0);
115 
116     if (n == -1) {
117         err = ngx_errno;
118         if (err == NGX_EAGAIN) {
119             return NGX_AGAIN;
120         }
121 
122         ngx_log_error(NGX_LOG_ALERT, log, err, "recvmsg() failed");
123         return NGX_ERROR;
124     }
125 
126     if (n == 0) {
127         ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "recvmsg() returned zero");
128         return NGX_ERROR;
129     }
130 
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);
134         return NGX_ERROR;
135     }
136 
137 #if (NGX_HAVE_MSGHDR_MSG_CONTROL)
138 
139     if (ch->command == NGX_CMD_OPEN_CHANNEL) {
140 
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");
144             return NGX_ERROR;
145         }
146 
147         if (cmsg.cm.cmsg_level != SOL_SOCKET || cmsg.cm.cmsg_type != SCM_RIGHTS)
148         {
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);
153             return NGX_ERROR;
154         }
155 
156         ch->fd = *(int *) CMSG_DATA(&cmsg.cm);
157     }
158 
159     if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) {
160         ngx_log_error(NGX_LOG_ALERT, log, 0,
161                       "recvmsg() truncated data");
162     }
163 
164 #else
165 
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");
170             return NGX_ERROR;
171         }
172 
173         ch->fd = fd;
174     }
175 
176 #endif
177 
178     return n;
179 }
180 
181 
182 ngx_int_t
183 ngx_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd, ngx_int_t event,
184     ngx_event_handler_pt handler)
185 {
186     ngx_event_t       *ev, *rev, *wev;
187     ngx_connection_t  *c;
188 
189     c = ngx_get_connection(fd, cycle->log);
190 
191     if (c == NULL) {
192         return NGX_ERROR;
193     }
194 
195     c->pool = cycle->pool;
196 
197     rev = c->read;
198     wev = c->write;
199 
200     rev->log = cycle->log;
201     wev->log = cycle->log;
202 
203 #if (NGX_THREADS)
204     rev->lock = &c->lock;
205     wev->lock = &c->lock;
206     rev->own_lock = &c->lock;
207     wev->own_lock = &c->lock;
208 #endif
209 
210     rev->channel = 1;
211     wev->channel = 1;
212 
213     ev = (event == NGX_READ_EVENT) ? rev : wev;
214 
215     ev->handler = handler;
216 
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);
220             return NGX_ERROR;
221         }
222 
223     } else {
224         if (ngx_add_event(ev, event, 0) == NGX_ERROR) {
225             ngx_free_connection(c);
226             return NGX_ERROR;
227         }
228     }
229 
230     return NGX_OK;
231 }
232 
233 
234 void
235 ngx_close_channel(ngx_fd_t *fd, ngx_log_t *log)
236 {
237     if (close(fd[0]) == -1) {
238         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "close() channel failed");
239     }
240 
241     if (close(fd[1]) == -1) {
242         ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "close() channel failed");
243     }
244 }
245 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.