aboutsummaryrefslogtreecommitdiffstats
path: root/slowcgi.c
diff options
context:
space:
mode:
authorflorian2013-10-23 15:29:21 +0000
committerWynn Wolf Arbor2020-05-24 12:33:55 +0200
commitae2ce6fc8e619b4ac5fd947994563410ef326756 (patch)
treed1b857f4c83a1a019840300ad5f2ff02501aaaa4 /slowcgi.c
parent709e7f6d4fbca1018ba06b1e2259cc708a4c9cee (diff)
downloadslowcgi-ae2ce6fc8e619b4ac5fd947994563410ef326756.tar.gz
We need to loop around waitpid to catch all exited children as we are not guaranteed to get one signal per child. pointed out by deraadt OK benno, blambert
Diffstat (limited to 'slowcgi.c')
-rw-r--r--slowcgi.c39
1 files changed, 20 insertions, 19 deletions
diff --git a/slowcgi.c b/slowcgi.c
index 1a0b819..8a9eed8 100644
--- a/slowcgi.c
+++ b/slowcgi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: slowcgi.c,v 1.23 2013/10/21 18:19:27 florian Exp $ */
+/* $OpenBSD: slowcgi.c,v 1.24 2013/10/23 15:29:21 florian Exp $ */
/*
* Copyright (c) 2013 David Gwynne <dlg@openbsd.org>
* Copyright (c) 2013 Florian Obser <florian@openbsd.org>
@@ -478,31 +478,32 @@ slowcgi_sig_handler(int sig, short event, void *arg)
int status;
p = arg;
- c = NULL;
switch (sig) {
case SIGCHLD:
- pid = wait(&status);
- SLIST_FOREACH(ncs, &p->requests, entry)
- if (ncs->request->script_pid == pid) {
- c = ncs->request;
- break;
+ while((pid = waitpid(WAIT_ANY, &status, WNOHANG)) != -1) {
+ c = NULL;
+ SLIST_FOREACH(ncs, &p->requests, entry)
+ if (ncs->request->script_pid == pid) {
+ c = ncs->request;
+ break;
+ }
+ if (c == NULL) {
+ lwarnx("caught exit of unknown child %i", pid);
+ continue;
}
- if (c == NULL) {
- lwarnx("caught exit of unknown child %i", pid);
- break;
- }
- if (WIFSIGNALED(status))
- c->script_status = WTERMSIG(status);
- else
- c->script_status = WEXITSTATUS(status);
+ if (WIFSIGNALED(status))
+ c->script_status = WTERMSIG(status);
+ else
+ c->script_status = WEXITSTATUS(status);
- if (c->script_flags == (STDOUT_DONE | STDERR_DONE))
- create_end_record(c);
- c->script_flags |= SCRIPT_DONE;
+ if (c->script_flags == (STDOUT_DONE | STDERR_DONE))
+ create_end_record(c);
+ c->script_flags |= SCRIPT_DONE;
- ldebug("wait: %s", c->script_name);
+ ldebug("wait: %s", c->script_name);
+ }
break;
case SIGPIPE:
/* ignore */