From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= <carenas@xxxxxxxxx> If the setup for the SIGCHLD signal handler sets SA_RESTART, poll() might not return with -1 and set errno to EINTR when a signal is received. Since the logic to reap zombie childs relies on those interruptions make sure to explicitly disable SA_RESTART around this function. Signed-off-by: Carlo Marcelo Arenas Belón <carenas@xxxxxxxxx> --- daemon.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/daemon.c b/daemon.c index 8133bd902157..01337fcfedab 100644 --- a/daemon.c +++ b/daemon.c @@ -1133,6 +1133,15 @@ static void set_signal_handler(struct sigaction *psa) sigaction(SIGCHLD, psa, NULL); } +static void set_sa_restart(struct sigaction *psa, int enable) +{ + if (enable) + psa->sa_flags |= SA_RESTART; + else + psa->sa_flags &= ~SA_RESTART; + sigaction(SIGCHLD, psa, NULL); +} + #else static void set_signal_handler(struct sigaction *psa UNUSED) @@ -1140,6 +1149,12 @@ static void set_signal_handler(struct sigaction *psa UNUSED) signal(SIGCHLD, child_handler); } +static void set_sa_restart(struct sigaction *psa UNUSED, int enable UNUSED) +{ +} + +#endif + static int service_loop(struct socketlist *socklist) { struct sigaction sa; @@ -1157,6 +1172,7 @@ static int service_loop(struct socketlist *socklist) for (;;) { check_dead_children(); + set_sa_restart(&sa, 0); if (poll(pfd, socklist->nr, -1) < 0) { if (errno != EINTR) { logerror("Poll failed, resuming: %s", @@ -1165,6 +1181,7 @@ static int service_loop(struct socketlist *socklist) } continue; } + set_sa_restart(&sa, 1); for (size_t i = 0; i < socklist->nr; i++) { if (pfd[i].revents & POLLIN) { -- gitgitgadget