aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorflorian2013-10-23 15:29:21 +0000
committerWynn Wolf Arbor2020-05-24 12:33:55 +0200
commitae2ce6fc8e619b4ac5fd947994563410ef326756 (patch)
treed1b857f4c83a1a019840300ad5f2ff02501aaaa4
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
-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 */