Mercurial > hg > nginx-vendor-0-5
comparison src/os/unix/ngx_freebsd_sendfile_chain.c @ 22:8b6db3bda591 NGINX_0_1_11
nginx 0.1.11
*) Feature: the worker_priority directive.
*) Change: both tcp_nopush and tcp_nodelay directives affect the
transferred response.
*) Bugfix: nginx did not call initgroups().
Thanks to Andrew Sitnikov and Andrei Nigmatulin.
*) Change: now the ngx_http_autoindex_module shows the file size in the
bytes.
*) Bugfix: the ngx_http_autoindex_module returned the 500 error if the
broken symlink was in a directory.
*) Bugfix: the files bigger than 4G could not be transferred using
sendfile.
*) Bugfix: if the backend was resolved to several backends and there
was an error while the response waiting then process may got caught
in an endless loop.
*) Bugfix: the worker process may exit with the "unknown cycle" message
when the /dev/poll method was used.
*) Bugfix: "close() channel failed" errors.
*) Bugfix: the autodetection of the "nobody" and "nogroup" groups.
*) Bugfix: the send_lowat directive did not work on Linux.
*) Bugfix: the segmentation fault occurred if there was no events
section in configuration.
*) Bugfix: nginx could not be built on OpenBSD.
*) Bugfix: the double slashes in "://" in the URI were converted to
":/".
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Thu, 02 Dec 2004 00:00:00 +0300 |
parents | 6f8b0dc0f8dd |
children | 45fe5b98a9de |
comparison
equal
deleted
inserted
replaced
21:4eeb9cfef970 | 22:8b6db3bda591 |
---|---|
35 ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, | 35 ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, |
36 off_t limit) | 36 off_t limit) |
37 { | 37 { |
38 int rc; | 38 int rc; |
39 u_char *prev; | 39 u_char *prev; |
40 off_t fprev, sent, send, sprev, aligned; | 40 off_t size, send, prev_send, aligned, sent, fprev; |
41 size_t hsize, fsize; | 41 size_t header_size, file_size; |
42 ssize_t size; | |
43 ngx_uint_t eintr, eagain, complete; | 42 ngx_uint_t eintr, eagain, complete; |
44 ngx_err_t err; | 43 ngx_err_t err; |
45 ngx_buf_t *file; | 44 ngx_buf_t *file; |
46 ngx_array_t header, trailer; | 45 ngx_array_t header, trailer; |
47 ngx_event_t *wev; | 46 ngx_event_t *wev; |
65 return NGX_CHAIN_ERROR; | 64 return NGX_CHAIN_ERROR; |
66 } | 65 } |
67 | 66 |
68 #endif | 67 #endif |
69 | 68 |
69 /* the maximum limit size is the maximum size_t value - the page size */ | |
70 | |
71 if (limit == 0 || limit > MAX_SIZE_T_VALUE - ngx_pagesize) { | |
72 limit = MAX_SIZE_T_VALUE - ngx_pagesize; | |
73 } | |
74 | |
70 send = 0; | 75 send = 0; |
71 eagain = 0; | 76 eagain = 0; |
72 | 77 |
73 header.elts = headers; | 78 header.elts = headers; |
74 header.size = sizeof(struct iovec); | 79 header.size = sizeof(struct iovec); |
80 trailer.nalloc = NGX_TRAILERS; | 85 trailer.nalloc = NGX_TRAILERS; |
81 trailer.pool = c->pool; | 86 trailer.pool = c->pool; |
82 | 87 |
83 for ( ;; ) { | 88 for ( ;; ) { |
84 file = NULL; | 89 file = NULL; |
85 fsize = 0; | 90 file_size = 0; |
86 hsize = 0; | 91 header_size = 0; |
87 eintr = 0; | 92 eintr = 0; |
88 complete = 0; | 93 complete = 0; |
89 sprev = send; | 94 prev_send = send; |
90 | 95 |
91 header.nelts = 0; | 96 header.nelts = 0; |
92 trailer.nelts = 0; | 97 trailer.nelts = 0; |
93 | 98 |
94 /* create the header iovec and coalesce the neighbouring bufs */ | 99 /* create the header iovec and coalesce the neighbouring bufs */ |
113 if (send + size > limit) { | 118 if (send + size > limit) { |
114 size = limit - send; | 119 size = limit - send; |
115 } | 120 } |
116 | 121 |
117 if (prev == cl->buf->pos) { | 122 if (prev == cl->buf->pos) { |
118 iov->iov_len += size; | 123 iov->iov_len += (size_t) size; |
119 | 124 |
120 } else { | 125 } else { |
121 if (!(iov = ngx_array_push(&header))) { | 126 if (!(iov = ngx_array_push(&header))) { |
122 return NGX_CHAIN_ERROR; | 127 return NGX_CHAIN_ERROR; |
123 } | 128 } |
124 | 129 |
125 iov->iov_base = (void *) cl->buf->pos; | 130 iov->iov_base = (void *) cl->buf->pos; |
126 iov->iov_len = size; | 131 iov->iov_len = (size_t) size; |
127 } | 132 } |
128 | 133 |
129 prev = cl->buf->pos + size; | 134 prev = cl->buf->pos + (size_t) size; |
130 hsize += size; | 135 header_size += (size_t) size; |
131 send += size; | 136 send += size; |
132 } | 137 } |
133 | 138 |
134 | 139 |
135 if (cl && cl->buf->in_file && send < limit) { | 140 if (cl && cl->buf->in_file && send < limit) { |
136 file = cl->buf; | 141 file = cl->buf; |
137 | 142 |
138 /* coalesce the neighbouring file bufs */ | 143 /* coalesce the neighbouring file bufs */ |
139 | 144 |
140 do { | 145 do { |
141 size = (size_t) (cl->buf->file_last - cl->buf->file_pos); | 146 size = cl->buf->file_last - cl->buf->file_pos; |
142 | 147 |
143 if (send + size > limit) { | 148 if (send + size > limit) { |
144 size = limit - send; | 149 size = limit - send; |
145 | 150 |
146 aligned = (cl->buf->file_pos + size + ngx_pagesize - 1) | 151 aligned = (cl->buf->file_pos + size + ngx_pagesize - 1) |
149 if (aligned <= cl->buf->file_last) { | 154 if (aligned <= cl->buf->file_last) { |
150 size = aligned - cl->buf->file_pos; | 155 size = aligned - cl->buf->file_pos; |
151 } | 156 } |
152 } | 157 } |
153 | 158 |
154 fsize += size; | 159 file_size += (size_t) size; |
155 send += size; | 160 send += size; |
156 fprev = cl->buf->file_pos + size; | 161 fprev = cl->buf->file_pos + size; |
157 cl = cl->next; | 162 cl = cl->next; |
158 | 163 |
159 } while (cl | 164 } while (cl |
187 if (send + size > limit) { | 192 if (send + size > limit) { |
188 size = limit - send; | 193 size = limit - send; |
189 } | 194 } |
190 | 195 |
191 if (prev == cl->buf->pos) { | 196 if (prev == cl->buf->pos) { |
192 iov->iov_len += size; | 197 iov->iov_len += (size_t) size; |
193 | 198 |
194 } else { | 199 } else { |
195 if (!(iov = ngx_array_push(&trailer))) { | 200 if (!(iov = ngx_array_push(&trailer))) { |
196 return NGX_CHAIN_ERROR; | 201 return NGX_CHAIN_ERROR; |
197 } | 202 } |
198 | 203 |
199 iov->iov_base = (void *) cl->buf->pos; | 204 iov->iov_base = (void *) cl->buf->pos; |
200 iov->iov_len = size; | 205 iov->iov_len = (size_t) size; |
201 } | 206 } |
202 | 207 |
203 prev = cl->buf->pos + size; | 208 prev = cl->buf->pos + (size_t) size; |
204 send += size; | 209 send += size; |
205 cl = cl->next; | 210 cl = cl->next; |
206 } | 211 } |
207 } | 212 } |
208 | 213 |
243 * the "nbytes bug" of the old sendfile() syscall: | 248 * the "nbytes bug" of the old sendfile() syscall: |
244 * http://www.freebsd.org/cgi/query-pr.cgi?pr=33771 | 249 * http://www.freebsd.org/cgi/query-pr.cgi?pr=33771 |
245 */ | 250 */ |
246 | 251 |
247 if (ngx_freebsd_sendfile_nbytes_bug == 0) { | 252 if (ngx_freebsd_sendfile_nbytes_bug == 0) { |
248 hsize = 0; | 253 header_size = 0; |
249 } | 254 } |
250 | 255 |
251 sent = 0; | 256 sent = 0; |
252 | 257 |
253 rc = sendfile(file->file->fd, c->fd, file->file_pos, | 258 rc = sendfile(file->file->fd, c->fd, file->file_pos, |
254 fsize + hsize, &hdtr, &sent, 0); | 259 file_size + header_size, &hdtr, &sent, 0); |
255 | 260 |
256 if (rc == -1) { | 261 if (rc == -1) { |
257 err = ngx_errno; | 262 err = ngx_errno; |
258 | 263 |
259 if (err == NGX_EAGAIN || err == NGX_EINTR) { | 264 if (err == NGX_EAGAIN || err == NGX_EINTR) { |
263 } else { | 268 } else { |
264 eagain = 1; | 269 eagain = 1; |
265 } | 270 } |
266 | 271 |
267 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err, | 272 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err, |
268 "sendfile() sent only %O bytes", | 273 "sendfile() sent only %O bytes", sent); |
269 sent); | |
270 | 274 |
271 } else { | 275 } else { |
272 wev->error = 1; | 276 wev->error = 1; |
273 ngx_connection_error(c, err, "sendfile() failed"); | 277 ngx_connection_error(c, err, "sendfile() failed"); |
274 return NGX_CHAIN_ERROR; | 278 return NGX_CHAIN_ERROR; |
289 return NGX_CHAIN_ERROR; | 293 return NGX_CHAIN_ERROR; |
290 } | 294 } |
291 | 295 |
292 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, | 296 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, |
293 "sendfile: %d, @%O %O:%uz", | 297 "sendfile: %d, @%O %O:%uz", |
294 rc, file->file_pos, sent, fsize + hsize); | 298 rc, file->file_pos, sent, file_size + header_size); |
295 | 299 |
296 } else { | 300 } else { |
297 rc = writev(c->fd, header.elts, header.nelts); | 301 rc = writev(c->fd, header.elts, header.nelts); |
298 | 302 |
299 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | 303 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
300 "writev: %d of %uz", rc, hsize); | 304 "writev: %d of %uz", rc, header_size); |
301 | 305 |
302 if (rc == -1) { | 306 if (rc == -1) { |
303 err = ngx_errno; | 307 err = ngx_errno; |
304 | 308 |
305 if (err == NGX_EAGAIN || err == NGX_EINTR) { | 309 if (err == NGX_EAGAIN || err == NGX_EINTR) { |
318 } | 322 } |
319 | 323 |
320 sent = rc > 0 ? rc : 0; | 324 sent = rc > 0 ? rc : 0; |
321 } | 325 } |
322 | 326 |
323 if (send - sprev == sent) { | 327 if (send - prev_send == sent) { |
324 complete = 1; | 328 complete = 1; |
325 } | 329 } |
326 | 330 |
327 c->sent += sent; | 331 c->sent += sent; |
328 | 332 |
351 | 355 |
352 continue; | 356 continue; |
353 } | 357 } |
354 | 358 |
355 if (ngx_buf_in_memory(cl->buf)) { | 359 if (ngx_buf_in_memory(cl->buf)) { |
356 cl->buf->pos += sent; | 360 cl->buf->pos += (size_t) sent; |
357 } | 361 } |
358 | 362 |
359 if (cl->buf->in_file) { | 363 if (cl->buf->in_file) { |
360 cl->buf->file_pos += sent; | 364 cl->buf->file_pos += sent; |
361 } | 365 } |