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