comparison src/os/unix/ngx_channel.c @ 366:e411b1482ee3

nginx-0.0.7-2004-06-23-19:18:17 import
author Igor Sysoev <igor@sysoev.ru>
date Wed, 23 Jun 2004 15:18:17 +0000
parents
children 02a511569afb
comparison
equal deleted inserted replaced
365:fd24ba70e1b3 366:e411b1482ee3
1
2 #include <ngx_config.h>
3 #include <ngx_core.h>
4 #include <ngx_channel.h>
5
6
7 ngx_int_t ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
8 ngx_log_t *log)
9 {
10 ssize_t n;
11 ngx_err_t err;
12 struct iovec iov[1];
13 struct msghdr msg;
14
15 #if (HAVE_MSGHDR_MSG_CONTROL)
16
17 union {
18 struct cmsghdr cm;
19 char space[CMSG_SPACE(sizeof(int))];
20 } cmsg;
21
22 if (ch->fd == -1) {
23 msg.msg_control = NULL;
24 msg.msg_controllen = 0;
25
26 } else {
27 msg.msg_control = (caddr_t) &cmsg;
28 msg.msg_controllen = sizeof(cmsg);
29
30 cmsg.cm.cmsg_len = sizeof(cmsg);
31 cmsg.cm.cmsg_level = SOL_SOCKET;
32 cmsg.cm.cmsg_type = SCM_RIGHTS;
33 *(int *) CMSG_DATA(&cmsg.cm) = ch->fd;
34 }
35
36 #else
37
38 if (ch->fd == -1) {
39 msg.msg_accrights = NULL;
40 msg.msg_accrightslen = 0;
41
42 } else {
43 msg.msg_accrights = (caddr_t) &ch->fd;
44 msg.msg_accrightslen = sizeof(int);
45 }
46
47 #endif
48
49 iov[0].iov_base = (char *) ch;
50 iov[0].iov_len = size;
51
52 msg.msg_name = NULL;
53 msg.msg_namelen = 0;
54 msg.msg_iov = iov;
55 msg.msg_iovlen = 1;
56
57 n = sendmsg(s, &msg, 0);
58
59 if (n == -1) {
60 err = ngx_errno;
61 if (err == NGX_EAGAIN) {
62 return NGX_AGAIN;
63 }
64
65 ngx_log_error(NGX_LOG_ALERT, log, err, "sendmsg() failed");
66 return NGX_ERROR;
67 }
68
69 return NGX_OK;
70 }
71
72
73 ngx_int_t ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
74 ngx_log_t *log)
75 {
76 ssize_t n;
77 ngx_err_t err;
78 struct iovec iov[1];
79 struct msghdr msg;
80
81 #if (HAVE_MSGHDR_MSG_CONTROL)
82 union {
83 struct cmsghdr cm;
84 char space[CMSG_SPACE(sizeof(int))];
85 } cmsg;
86 #else
87 int fd;
88 #endif
89
90 iov[0].iov_base = (char *) ch;
91 iov[0].iov_len = size;
92
93 msg.msg_name = NULL;
94 msg.msg_namelen = 0;
95 msg.msg_iov = iov;
96 msg.msg_iovlen = 1;
97
98 #if (HAVE_MSGHDR_MSG_CONTROL)
99 msg.msg_control = (caddr_t) &cmsg;
100 msg.msg_controllen = sizeof(cmsg);
101 #else
102 msg.msg_accrights = (caddr_t) &fd;
103 msg.msg_accrightslen = sizeof(int);
104 #endif
105
106 n = recvmsg(s, &msg, 0);
107
108 if (n == -1) {
109 err = ngx_errno;
110 if (err == NGX_EAGAIN) {
111 return NGX_AGAIN;
112 }
113
114 ngx_log_error(NGX_LOG_ALERT, log, err, "recvmsg() failed");
115 return NGX_ERROR;
116 }
117
118 if ((size_t) n < sizeof(ngx_channel_t)) {
119 ngx_log_error(NGX_LOG_ALERT, log, 0,
120 "recvmsg() returned not enough data");
121 return NGX_ERROR;
122 }
123
124 #if (HAVE_MSGHDR_MSG_CONTROL)
125
126 if (ch->command == NGX_CMD_OPEN_CHANNEL) {
127
128 if (cmsg.cm.cmsg_len < sizeof(cmsg)) {
129 ngx_log_error(NGX_LOG_ALERT, log, 0,
130 "recvmsg() returned too small ancillary data");
131 return NGX_ERROR;
132 }
133
134 if (cmsg.cm.cmsg_level != SOL_SOCKET || cmsg.cm.cmsg_type != SCM_RIGHTS)
135 {
136 ngx_log_error(NGX_LOG_ALERT, log, 0,
137 "recvmsg() returned invalid ancillary data "
138 "level %d or type %d",
139 cmsg.cm.cmsg_level, cmsg.cm.cmsg_type);
140 return NGX_ERROR;
141 }
142
143 ch->fd = *(int *) CMSG_DATA(&cmsg.cm);
144 }
145
146 if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) {
147 ngx_log_error(NGX_LOG_ALERT, log, 0,
148 "recvmsg() truncated data");
149 }
150
151 #else
152
153 if (ch->command == NGX_CMD_OPEN_CHANNEL) {
154 if (msg.msg_accrightslen != sizeof(int)) {
155 ngx_log_error(NGX_LOG_ALERT, log, 0,
156 "recvmsg() returned no ancillary data");
157 return NGX_ERROR;
158 }
159
160 ch->fd = fd;
161 }
162
163 #endif
164
165 return n;
166 }
167
168
169 ngx_int_t ngx_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd,
170 ngx_int_t event, ngx_event_handler_pt handler)
171 {
172 ngx_event_t *ev, *rev, *wev;
173 ngx_connection_t *c;
174
175 c = &cycle->connections[fd];
176 rev = &cycle->read_events[fd];
177 wev = &cycle->write_events[fd];
178
179 ngx_memzero(c, sizeof(ngx_connection_t));
180 ngx_memzero(rev, sizeof(ngx_event_t));
181 ngx_memzero(wev, sizeof(ngx_event_t));
182
183 c->fd = fd;
184 c->pool = cycle->pool;
185
186 c->read = rev;
187 c->write = wev;
188
189 c->log = cycle->log;
190 rev->log = cycle->log;
191 wev->log = cycle->log;
192 rev->index = NGX_INVALID_INDEX;
193 wev->index = NGX_INVALID_INDEX;
194 rev->data = c;
195 wev->data = c;
196
197 ev = (event == NGX_READ_EVENT) ? rev : wev;
198
199 ev->event_handler = handler;
200
201 if (ngx_add_conn) {
202 if (ngx_add_conn(c) == NGX_ERROR) {
203 return NGX_ERROR;
204 }
205
206 } else {
207 if (ngx_add_event(ev, event, 0) == NGX_ERROR) {
208 return NGX_ERROR;
209 }
210 }
211
212 return NGX_OK;
213 }