Skip to content

Commit 851d663

Browse files
committed
daemon: explicitly allow EINTR during poll()
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 <[email protected]>
1 parent c66bda4 commit 851d663

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

daemon.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,25 @@ static void socksetup(struct string_list *listen_addr, int listen_port, struct s
11161116
}
11171117
}
11181118

1119+
#ifndef NO_RESTARTABLE_SIGNALS
1120+
1121+
static void set_sa_restart(struct sigaction *psa, int enable)
1122+
{
1123+
if (enable)
1124+
psa->sa_flags |= SA_RESTART;
1125+
else
1126+
psa->sa_flags &= ~SA_RESTART;
1127+
sigaction(SIGCHLD, psa, NULL);
1128+
}
1129+
1130+
#else
1131+
1132+
static void set_sa_restart(struct sigaction *psa UNUSED, int enable UNUSED)
1133+
{
1134+
}
1135+
1136+
#endif
1137+
11191138
static int service_loop(struct socketlist *socklist)
11201139
{
11211140
struct sigaction sa;
@@ -1136,6 +1155,7 @@ static int service_loop(struct socketlist *socklist)
11361155
for (;;) {
11371156
check_dead_children();
11381157

1158+
set_sa_restart(&sa, 0);
11391159
if (poll(pfd, socklist->nr, -1) < 0) {
11401160
if (errno != EINTR) {
11411161
logerror("Poll failed, resuming: %s",
@@ -1144,6 +1164,7 @@ static int service_loop(struct socketlist *socklist)
11441164
}
11451165
continue;
11461166
}
1167+
set_sa_restart(&sa, 1);
11471168

11481169
for (size_t i = 0; i < socklist->nr; i++) {
11491170
if (pfd[i].revents & POLLIN) {

0 commit comments

Comments
 (0)