223 * Try to flush the CGIHandler write buffer |
223 * Try to flush the CGIHandler write buffer |
224 * |
224 * |
225 * When successful, cgi_try_write_flush() returns 0. If an error occurs, |
225 * When successful, cgi_try_write_flush() returns 0. If an error occurs, |
226 * 1 is returned. |
226 * 1 is returned. |
227 * |
227 * |
228 * If the error is not EWOULDBLOCK, handler->result is set to REQ_ABORTED. |
228 * If the error is not EAGAIN, handler->result is set to REQ_ABORTED. |
229 */ |
229 */ |
230 static int cgi_try_write_flush(CGIHandler *handler, Session *sn) { |
230 static int cgi_try_write_flush(CGIHandler *handler, Session *sn) { |
231 ssize_t wr = 0; |
231 ssize_t wr = 0; |
232 while( |
232 while( |
233 handler->writebuf_size - handler->writebuf_pos > 0 && |
233 handler->writebuf_size - handler->writebuf_pos > 0 && |
239 { |
239 { |
240 handler->writebuf_pos += wr; |
240 handler->writebuf_pos += wr; |
241 handler->count_write += wr; |
241 handler->count_write += wr; |
242 } |
242 } |
243 if(handler->writebuf_size - handler->writebuf_pos > 0) { |
243 if(handler->writebuf_size - handler->writebuf_pos > 0) { |
244 if(net_errno(sn->csd) != EWOULDBLOCK) { |
244 if(net_errno(sn->csd) != EAGAIN) { |
245 handler->result = REQ_ABORTED; |
245 handler->result = REQ_ABORTED; |
246 log_ereport( |
246 log_ereport( |
247 LOG_FAILURE, |
247 LOG_FAILURE, |
248 "cgi pid %d %s: network error: %s", |
248 "cgi pid %d %s: network error: %s", |
249 (int)handler->process.pid, |
249 (int)handler->process.pid, |
259 /* |
259 /* |
260 * Try to write the buffer to sn->csd |
260 * Try to write the buffer to sn->csd |
261 * In case the socket is non-blocking and not all bytes could be written, |
261 * In case the socket is non-blocking and not all bytes could be written, |
262 * the remaining bytes are copied to the CGIHandler write buffer. |
262 * the remaining bytes are copied to the CGIHandler write buffer. |
263 * |
263 * |
264 * If an error occurs that is not EWOULDBLOCK, handler->result is set to |
264 * If an error occurs that is not EAGAIN, handler->result is set to |
265 * REQ_ABORTED. |
265 * REQ_ABORTED. |
266 * |
266 * |
267 * Returns 0 if all bytes are successfully written, otherwise 1 |
267 * Returns 0 if all bytes are successfully written, otherwise 1 |
268 */ |
268 */ |
269 static int cgi_try_write(CGIHandler *handler, EventHandler *ev, Session *sn, char *buf, size_t size) { |
269 static int cgi_try_write(CGIHandler *handler, EventHandler *ev, Session *sn, char *buf, size_t size) { |
274 pos += wr; |
274 pos += wr; |
275 handler->count_write += wr; |
275 handler->count_write += wr; |
276 } |
276 } |
277 |
277 |
278 if(pos < size) { |
278 if(pos < size) { |
279 if(net_errno(sn->csd) == EWOULDBLOCK) { |
279 if(net_errno(sn->csd) == EAGAIN) { |
280 // copy remaining bytes to the write buffer |
280 // copy remaining bytes to the write buffer |
281 // we assume there are no remaining bytes in writebuf |
281 // we assume there are no remaining bytes in writebuf |
282 size_t remaining = size-pos; |
282 size_t remaining = size-pos; |
283 if(remaining > handler->writebuf_alloc) { |
283 if(remaining > handler->writebuf_alloc) { |
284 handler->writebuf_alloc = size > 4096 ? size : 4096; |
284 handler->writebuf_alloc = size > 4096 ? size : 4096; |
447 if(send_response < 0) { |
447 if(send_response < 0) { |
448 handler->result = REQ_ABORTED; |
448 handler->result = REQ_ABORTED; |
449 ret = CGI_IO_ERROR; |
449 ret = CGI_IO_ERROR; |
450 break; |
450 break; |
451 } else if(send_response == 1) { |
451 } else if(send_response == 1) { |
452 // EWOULDBLOCK |
452 // EAGAIN |
453 if(!handler->poll_out) { |
453 if(!handler->poll_out) { |
454 if(event_pollout(ev, sn->csd, handler->writeev)) { |
454 if(event_pollout(ev, sn->csd, handler->writeev)) { |
455 handler->result = REQ_ABORTED; |
455 handler->result = REQ_ABORTED; |
456 return CGI_IO_ERROR; |
456 return CGI_IO_ERROR; |
457 } |
457 } |
473 if(cgi_try_write(handler, ev, sn, buf, r)) { |
473 if(cgi_try_write(handler, ev, sn, buf, r)) { |
474 return handler->result == REQ_ABORTED ? CGI_IO_ERROR : CGI_IO_NEED_WRITE; |
474 return handler->result == REQ_ABORTED ? CGI_IO_ERROR : CGI_IO_NEED_WRITE; |
475 } |
475 } |
476 } |
476 } |
477 } |
477 } |
478 if(r < 0 && errno == EWOULDBLOCK) { |
478 if(r < 0 && errno == EAGAIN) { |
479 return CGI_IO_NEED_READ; |
479 return CGI_IO_NEED_READ; |
480 } |
480 } |
481 handler->cgi_eof = TRUE; |
481 handler->cgi_eof = TRUE; |
482 log_ereport(LOG_DEBUG, "cgi-send: req: %p pid: %d set cgi_eof : %s", rq, handler->process.pid, debug_log); |
482 log_ereport(LOG_DEBUG, "cgi-send: req: %p pid: %d set cgi_eof : %s", rq, handler->process.pid, debug_log); |
483 return ret; |
483 return ret; |