src/server/safs/cgi.c

changeset 499
ef77854a91f3
parent 498
0d80f8a2b29f
child 501
2aa6bd9f166f
equal deleted inserted replaced
498:0d80f8a2b29f 499:ef77854a91f3
172 172
173 Event *stderr_readev = pool_malloc(sn->pool, sizeof(Event)); 173 Event *stderr_readev = pool_malloc(sn->pool, sizeof(Event));
174 ZERO(stderr_readev, sizeof(Event)); 174 ZERO(stderr_readev, sizeof(Event));
175 stderr_readev->cookie = handler; 175 stderr_readev->cookie = handler;
176 stderr_readev->fn = cgi_stderr_readevent; 176 stderr_readev->fn = cgi_stderr_readevent;
177 stderr_readev->finish = NULL; 177 stderr_readev->finish = cgi_event_finish;
178 178
179 Event *writeev = pool_malloc(sn->pool, sizeof(Event)); 179 Event *writeev = pool_malloc(sn->pool, sizeof(Event));
180 ZERO(writeev, sizeof(Event)); 180 ZERO(writeev, sizeof(Event));
181 writeev->cookie = handler; 181 writeev->cookie = handler;
182 writeev->fn = cgi_writeevent;
183 writeev->finish = cgi_event_finish;
182 184
183 185
184 handler->writeev = writeev; 186 handler->writeev = writeev;
185 handler->stderrev = stderr_readev;
186 187
187 net_setnonblock(sn->csd, 1); 188 net_setnonblock(sn->csd, 1);
188 189
189 // add poll events for cgi stdout/stderr 190 // add poll events for cgi stdout/stderr
190 int error = 0; 191 int error = 0;
194 } 195 }
195 if(ev_pollin(sn->ev, handler->process.out[0], readev)) { 196 if(ev_pollin(sn->ev, handler->process.out[0], readev)) {
196 log_ereport(LOG_FAILURE, "send-cgi: stdout ev_pollin failed"); 197 log_ereport(LOG_FAILURE, "send-cgi: stdout ev_pollin failed");
197 error = 1; 198 error = 1;
198 } 199 }
200
201 handler->events = 2; // 2 events (stdout, stderr)
199 202
200 if(error) { 203 if(error) {
201 log_ereport(LOG_FAILURE, "cgi-send: kill script: %s", path); 204 log_ereport(LOG_FAILURE, "cgi-send: kill script: %s", path);
202 kill(handler->process.pid, SIGKILL); 205 kill(handler->process.pid, SIGKILL);
203 cgi_parser_free(handler->parser); 206 cgi_parser_free(handler->parser);
256 if(!handler->poll_out) { 259 if(!handler->poll_out) {
257 if(event_pollout(ev, sn->csd, handler->writeev)) { 260 if(event_pollout(ev, sn->csd, handler->writeev)) {
258 handler->result = REQ_ABORTED; 261 handler->result = REQ_ABORTED;
259 return 0; 262 return 0;
260 } 263 }
264 handler->events++;
261 handler->poll_out = TRUE; 265 handler->poll_out = TRUE;
262 } 266 }
263 } else { 267 } else {
264 handler->result = REQ_ABORTED; 268 handler->result = REQ_ABORTED;
265 log_ereport(LOG_FAILURE, "cgi_try_write: %s", strerror(errno)); 269 log_ereport(LOG_FAILURE, "cgi_try_write: %s", strerror(errno));
365 } 369 }
366 if(r < 0 && errno == EWOULDBLOCK) { 370 if(r < 0 && errno == EWOULDBLOCK) {
367 return 1; 371 return 1;
368 } 372 }
369 373
370 handler->read_output_finished = TRUE;
371 return 0; 374 return 0;
372 } 375 }
373 376
374 int cgi_stderr_readevent(EventHandler *ev, Event *event) { 377 int cgi_stderr_readevent(EventHandler *ev, Event *event) {
375 CGIHandler *handler = event->cookie; 378 CGIHandler *handler = event->cookie;
454 } 457 }
455 458
456 if(handler->stderr_tmp) { 459 if(handler->stderr_tmp) {
457 pool_free(handler->parser->sn->pool, handler->stderr_tmp); 460 pool_free(handler->parser->sn->pool, handler->stderr_tmp);
458 } 461 }
459 handler->stderr_finished = TRUE;
460 return 0; 462 return 0;
461 } 463 }
462 464
463 int cgi_event_finish(EventHandler *ev, Event *event) { 465 int cgi_event_finish(EventHandler *ev, Event *event) {
464 CGIHandler *handler = event->cookie; 466 CGIHandler *handler = event->cookie;
465 CGIResponseParser *parser = handler->parser; 467 CGIResponseParser *parser = handler->parser;
466 Session *sn = parser->sn; 468 Session *sn = parser->sn;
467 Request *rq = parser->rq; 469 Request *rq = parser->rq;
468 470
469 log_ereport(LOG_DEBUG, "cgi-send: req: %p event-finish", rq); 471 log_ereport(LOG_DEBUG, "cgi-send: req: %p event-finish %d", rq, handler->events);
472 if(--handler->events > 0) {
473 return 0;
474 }
475
470 if(handler->result == REQ_ABORTED && handler->process.pid != 0) { 476 if(handler->result == REQ_ABORTED && handler->process.pid != 0) {
471 log_ereport(LOG_FAILURE, "cgi-send: kill script: %s", handler->path); 477 log_ereport(LOG_FAILURE, "cgi-send: kill script: %s", handler->path);
472
473 killpg(handler->process.pid, SIGTERM); 478 killpg(handler->process.pid, SIGTERM);
474 479 }
475 handler->process.pid = 0; 480
476 } 481 log_ereport(LOG_DEBUG, "cgi-send: req: %p cgi_close", rq);
477
478 if(!handler->stderr_finished) {
479 // stderr handler is still active
480 // set stderr event finish function, to run the finish code later
481 handler->stderrev->finish = cgi_event_finish;
482 return 0;
483 }
484 if(handler->poll_out && !handler->send_response_finished) {
485 // send response is still active
486 handler->writeev->finish = cgi_event_finish;
487 return 0;
488 }
489 482
490 int exit_code = cgi_close(&handler->process); 483 int exit_code = cgi_close(&handler->process);
491 if(exit_code != 0) { 484 if(exit_code != 0) {
492 log_ereport(LOG_FAILURE, "send-cgi: script: %s exited with code %d", handler->path, exit_code); 485 log_ereport(LOG_FAILURE, "send-cgi: script: %s exited with code %d", handler->path, exit_code);
493 handler->result = REQ_ABORTED; 486 handler->result = REQ_ABORTED;

mercurial