static void cgi_connection_close(server *srv, handler_ctx *hctx) { plugin_data *p = hctx->plugin_data; connection *con = hctx->remote_conn; /* the connection to the browser went away, but we still have a connection * to the CGI script * * close cgi-connection */ if (hctx->fd != -1) { /* close connection to the cgi-script */ fdevent_fdnode_event_del(srv->ev, hctx->fdn); /*fdevent_unregister(srv->ev, hctx->fd);*//*(handled below)*/ fdevent_sched_close(srv->ev, hctx->fd, 0); hctx->fdn = NULL; } if (hctx->fdtocgi != -1) { cgi_connection_close_fdtocgi(srv, hctx); /*(closes only hctx->fdtocgi)*/ } if (hctx->pid > 0) { cgi_pid_kill(p, hctx->pid); } con->plugin_ctx[p->id] = NULL; cgi_handler_ctx_free(hctx); /* finish response (if not already con->file_started, con->file_finished) */ if (con->mode == p->id) { http_response_backend_done(srv, con); } }
static void cgi_connection_close(server *srv, handler_ctx *hctx) { int status; pid_t pid; plugin_data *p = hctx->plugin_data; connection *con = hctx->remote_conn; #ifndef __WIN32 /* the connection to the browser went away, but we still have a connection * to the CGI script * * close cgi-connection */ if (hctx->fd != -1) { /* close connection to the cgi-script */ fdevent_event_del(srv->ev, &(hctx->fde_ndx), hctx->fd); fdevent_unregister(srv->ev, hctx->fd); fdevent_sched_close(srv->ev, hctx->fd, 0); } if (hctx->fdtocgi != -1) { cgi_connection_close_fdtocgi(srv, hctx); /*(closes only hctx->fdtocgi)*/ } pid = hctx->pid; con->plugin_ctx[p->id] = NULL; cgi_handler_ctx_free(hctx); /* if waitpid hasn't been called by response.c yet, do it here */ if (pid) { /* check if the CGI-script is already gone */ switch(waitpid(pid, &status, WNOHANG)) { case 0: /* not finished yet */ #if 0 log_error_write(srv, __FILE__, __LINE__, "sd", "(debug) child isn't done yet, pid:", pid); #endif break; case -1: /* */ if (errno == EINTR) break; /* * errno == ECHILD happens if _subrequest catches the process-status before * we have read the response of the cgi process * * -> catch status * -> WAIT_FOR_EVENT * -> read response * -> we get here with waitpid == ECHILD * */ if (errno != ECHILD) { log_error_write(srv, __FILE__, __LINE__, "ss", "waitpid failed: ", strerror(errno)); } /* anyway: don't wait for it anymore */ pid = 0; break; default: if (WIFEXITED(status)) { #if 0 log_error_write(srv, __FILE__, __LINE__, "sd", "(debug) cgi exited fine, pid:", pid); #endif } else { log_error_write(srv, __FILE__, __LINE__, "sd", "cgi died, pid:", pid); } pid = 0; break; } if (pid) { kill(pid, SIGTERM); /* cgi-script is still alive, queue the PID for removal */ cgi_pid_add(srv, p, pid); } } #endif /* finish response (if not already con->file_started, con->file_finished) */ if (con->mode == p->id) { http_response_backend_done(srv, con); } }