コード例 #1
0
ファイル: mod_cgi.c プロジェクト: gstrauss/lighttpd1.4
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);
	}
}
コード例 #2
0
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);
	}
}