From: Tomek Mrugalski Date: Tue, 18 Aug 2015 12:08:00 +0000 (+0200) Subject: [support8785] Likely fix for the issues with "no child processes" exception X-Git-Tag: trac4003_base~1^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=861397d1c71fa5c1c8ac84cf4d086b048dcf5d45;p=thirdparty%2Fkea.git [support8785] Likely fix for the issues with "no child processes" exception This fix makes the signal handler no longer modify errno value. That was causing "no child processes" exceptions in places that had nothing to do with signals or processes. --- diff --git a/src/lib/util/process_spawn.cc b/src/lib/util/process_spawn.cc index 34e8dba193..0870e934a4 100644 --- a/src/lib/util/process_spawn.cc +++ b/src/lib/util/process_spawn.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -279,6 +280,11 @@ ProcessSpawnImpl::waitForProcess(int signum) { if (signum != SIGCHLD) { return (false); } + + // Need to store current value of errno, so we could restore it + // after this signal handler does his work. + int errno_value = errno; + for (;;) { int status = 0; pid_t pid = waitpid(-1, &status, WNOHANG); @@ -294,6 +300,16 @@ ProcessSpawnImpl::waitForProcess(int signum) { proc->second.running_ = false; } } + + // Need to restore previous value of errno. We called waitpid(), + // which likely indicated its result by setting errno to ECHILD. + // This is a signal handler, which can be called while virtually + // any other code being run. If we're unlucky, we could receive a + // signal when running a code that is about to check errno. As a + // result the code would detect errno=ECHILD in places which are + // completely unrelated to child or processes in general. + errno = errno_value; + return (true); }