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 | |
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
-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 */ |