Mercurial > hg > nginx
comparison src/os/unix/ngx_solaris_sendfilev_chain.c @ 6438:646985c55393
Truncation detection in sendfilev() on Solaris.
While sendfilev() is documented to return -1 with EINVAL set
if the file was truncated, at least Solaris 11 silently returns 0,
and this results in CPU hog. Added a test to complain appropriately
if 0 is returned.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 15 Mar 2016 18:26:59 +0300 |
parents | 4dd67e5d958e |
children |
comparison
equal
deleted
inserted
replaced
6437:4df3d9fcdee8 | 6438:646985c55393 |
---|---|
46 off_t size, send, prev_send, aligned, fprev; | 46 off_t size, send, prev_send, aligned, fprev; |
47 size_t sent; | 47 size_t sent; |
48 ssize_t n; | 48 ssize_t n; |
49 ngx_int_t eintr; | 49 ngx_int_t eintr; |
50 ngx_err_t err; | 50 ngx_err_t err; |
51 ngx_buf_t *file; | |
51 ngx_uint_t nsfv; | 52 ngx_uint_t nsfv; |
52 sendfilevec_t *sfv, sfvs[NGX_SENDFILEVECS]; | 53 sendfilevec_t *sfv, sfvs[NGX_SENDFILEVECS]; |
53 ngx_event_t *wev; | 54 ngx_event_t *wev; |
54 ngx_chain_t *cl; | 55 ngx_chain_t *cl; |
55 | 56 |
75 | 76 |
76 for ( ;; ) { | 77 for ( ;; ) { |
77 fd = SFV_FD_SELF; | 78 fd = SFV_FD_SELF; |
78 prev = NULL; | 79 prev = NULL; |
79 fprev = 0; | 80 fprev = 0; |
81 file = NULL; | |
80 sfv = NULL; | 82 sfv = NULL; |
81 eintr = 0; | 83 eintr = 0; |
82 sent = 0; | 84 sent = 0; |
83 prev_send = send; | 85 prev_send = send; |
84 | 86 |
151 sfv->sfv_flag = 0; | 153 sfv->sfv_flag = 0; |
152 sfv->sfv_off = cl->buf->file_pos; | 154 sfv->sfv_off = cl->buf->file_pos; |
153 sfv->sfv_len = (size_t) size; | 155 sfv->sfv_len = (size_t) size; |
154 } | 156 } |
155 | 157 |
158 file = cl->buf; | |
156 fprev = cl->buf->file_pos + size; | 159 fprev = cl->buf->file_pos + size; |
157 send += size; | 160 send += size; |
158 } | 161 } |
159 } | 162 } |
160 | 163 |
177 return NGX_CHAIN_ERROR; | 180 return NGX_CHAIN_ERROR; |
178 } | 181 } |
179 | 182 |
180 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err, | 183 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, err, |
181 "sendfilev() sent only %uz bytes", sent); | 184 "sendfilev() sent only %uz bytes", sent); |
185 | |
186 } else if (n == 0 && sent == 0) { | |
187 | |
188 /* | |
189 * sendfilev() is documented to return -1 with errno | |
190 * set to EINVAL if svf_len is greater than the file size, | |
191 * but at least Solaris 11 returns 0 instead | |
192 */ | |
193 | |
194 if (file) { | |
195 ngx_log_error(NGX_LOG_ALERT, c->log, 0, | |
196 "sendfilev() reported that \"%s\" was truncated at %O", | |
197 file->file->name.data, file->file_pos); | |
198 | |
199 } else { | |
200 ngx_log_error(NGX_LOG_ALERT, c->log, 0, | |
201 "sendfilev() returned 0 with memory buffers"); | |
202 } | |
203 | |
204 return NGX_CHAIN_ERROR; | |
182 } | 205 } |
183 | 206 |
184 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | 207 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
185 "sendfilev: %z %z", n, sent); | 208 "sendfilev: %z %z", n, sent); |
186 | 209 |