diff options
author | florian | 2013-10-23 15:29:21 +0000 |
---|---|---|
committer | Wynn Wolf Arbor | 2020-05-24 12:33:55 +0200 |
commit | ae2ce6fc8e619b4ac5fd947994563410ef326756 (patch) | |
tree | d1b857f4c83a1a019840300ad5f2ff02501aaaa4 /slowcgi.c | |
parent | 709e7f6d4fbca1018ba06b1e2259cc708a4c9cee (diff) | |
download | slowcgi-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.c | 39 |
1 files changed, 20 insertions, 19 deletions
@@ -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 */ |