225 } |
225 } |
226 if(wr < 0) { |
226 if(wr < 0) { |
227 if(errno != EWOULDBLOCK) { |
227 if(errno != EWOULDBLOCK) { |
228 handler->result = REQ_ABORTED; |
228 handler->result = REQ_ABORTED; |
229 } |
229 } |
|
230 handler->wait_write = TRUE; |
230 return 1; |
231 return 1; |
|
232 } else { |
|
233 handler->wait_write = FALSE; |
231 } |
234 } |
232 return 0; |
235 return 0; |
233 } |
236 } |
234 |
237 |
235 static int cgi_try_write(CGIHandler *handler, EventHandler *ev, Session *sn, char *buf, size_t size) { |
238 static int cgi_try_write(CGIHandler *handler, EventHandler *ev, Session *sn, char *buf, size_t size) { |
|
239 handler->wait_write = FALSE; |
236 size_t pos = 0; |
240 size_t pos = 0; |
237 ssize_t wr = 0; |
241 ssize_t wr = 0; |
238 while(size - pos > 0 && (wr = net_write(sn->csd, buf + pos, size - pos)) > 0) { |
242 while(size - pos > 0 && (wr = net_write(sn->csd, buf + pos, size - pos)) > 0) { |
239 pos += wr; |
243 pos += wr; |
240 } |
244 } |
296 |
301 |
297 // try to flush handler->writebuf |
302 // try to flush handler->writebuf |
298 // if writebuf is empty, this does nothing and returns 0 |
303 // if writebuf is empty, this does nothing and returns 0 |
299 if(cgi_try_write_flush(handler, sn)) { |
304 if(cgi_try_write_flush(handler, sn)) { |
300 if(handler->result == REQ_ABORTED) { |
305 if(handler->result == REQ_ABORTED) { |
301 log_ereport(LOG_DEBUG, "cgi-send: req: %p write failed: abort", rq); |
306 log_ereport(LOG_DEBUG, "cgi-send: req: %p write failed: %s: abort", strerror(errno), rq); |
302 return 0; |
307 return 0; |
303 } else { |
308 } else { |
304 return 1; |
309 return 1; |
305 } |
310 } |
306 } |
311 } |
465 int cgi_event_finish(EventHandler *ev, Event *event) { |
470 int cgi_event_finish(EventHandler *ev, Event *event) { |
466 CGIHandler *handler = event->cookie; |
471 CGIHandler *handler = event->cookie; |
467 CGIResponseParser *parser = handler->parser; |
472 CGIResponseParser *parser = handler->parser; |
468 Session *sn = parser->sn; |
473 Session *sn = parser->sn; |
469 Request *rq = parser->rq; |
474 Request *rq = parser->rq; |
470 |
475 |
471 log_ereport(LOG_DEBUG, "cgi-send: req: %p event-finish %d", rq, handler->events); |
|
472 if(--handler->events > 0) { |
476 if(--handler->events > 0) { |
473 return 0; |
477 if(handler->events == 1 && handler->poll_out && !handler->wait_write) { |
|
478 // write event registered, however it will not be activated anymore |
|
479 // we can safely remove the event |
|
480 if(event_removepoll(ev, sn->csd)) { |
|
481 log_ereport(LOG_FAILURE, "cgi_event_finish: event_removepoll: %s", strerror(errno)); |
|
482 } |
|
483 } else { |
|
484 return 0; |
|
485 } |
474 } |
486 } |
475 |
487 |
476 if(handler->result == REQ_ABORTED && handler->process.pid != 0) { |
488 if(handler->result == REQ_ABORTED && handler->process.pid != 0) { |
477 log_ereport(LOG_FAILURE, "cgi-send: kill script: %s", handler->path); |
489 log_ereport(LOG_FAILURE, "cgi-send: kill script: %s", handler->path); |
478 killpg(handler->process.pid, SIGTERM); |
490 killpg(handler->process.pid, SIGTERM); |