-/* $OpenBSD: slowcgi.c,v 1.2 2022/07/08 08:48:56 claudio Exp $ */
+/* $OpenBSD: slowcgi.c,v 1.3 2022/08/12 13:24:30 claudio Exp $ */
/*
* Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
#include "bgplgd.h"
#include "http.h"
-#define TIMEOUT_DEFAULT 120
+#define TIMEOUT_DEFAULT 30
#define WWW_USER "www"
#define BGPLGD_USER "_bgplgd"
struct event tmo;
struct event script_ev;
struct event script_err_ev;
- int fd;
+ struct fcgi_response_head response_head;
+ struct env_head env;
uint8_t buf[FCGI_RECORD_SIZE];
size_t buf_pos;
size_t buf_len;
- struct fcgi_response_head response_head;
- struct env_head env;
+ int fd;
int env_count;
+ int inflight_fds_accounted;
pid_t command_pid;
int command_status;
int script_flags;
uint16_t id;
uint8_t request_started;
uint8_t request_done;
- int inflight_fds_accounted;
+ uint8_t timeout_fired;
};
LIST_HEAD(requests_head, request);
}
struct timeval timeout = { TIMEOUT_DEFAULT, 0 };
+struct timeval kill_timeout = { 5, 0 };
struct slowcgi_proc slowcgi_proc;
int debug = 0;
int on = 1;
void
slowcgi_timeout(int fd, short events, void *arg)
{
- cleanup_request((struct request*) arg);
+ struct request *c = arg;
+ int sig = SIGTERM;
+
+ if (c->script_flags & SCRIPT_DONE)
+ return;
+
+ ldebug("timeout fired");
+
+ if (c->timeout_fired)
+ sig = SIGKILL;
+
+ if (kill(c->command_pid, sig) == -1) {
+ lwarn("kill child %d after timeout", c->command_pid);
+ if (event_initialized(&c->script_ev)) {
+ close(EVENT_FD(&c->script_ev));
+ event_del(&c->script_ev);
+ }
+ if (event_initialized(&c->script_err_ev)) {
+ close(EVENT_FD(&c->script_err_ev));
+ event_del(&c->script_err_ev);
+ }
+
+ c->command_status = SIGALRM;
+ c->script_flags = STDOUT_DONE | STDERR_DONE | SCRIPT_DONE;
+ create_end_record(c);
+ }
+
+ if (c->timeout_fired++ == 0)
+ evtimer_add(&c->tmo, &kill_timeout);
}
void
if (c->command_pid == pid)
break;
if (c == NULL) {
- lwarnx("caught exit of unknown child %i", pid);
+ lwarnx("caught exit of unknown child %d", pid);
continue;
}
c->command_status = WEXITSTATUS(status);
ldebug("exit %s%d",
- WIFSIGNALED(status) ? "signal" : "",
+ WIFSIGNALED(status) ? "signal " : "",
c->command_status);
c->script_flags |= SCRIPT_DONE;