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
Diffstat (limited to '')
-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 */