From f21e8ff5c9df0989ce09b3d9a50c0dc81af18837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= Date: Wed, 25 Jun 2025 20:32:08 -0700 Subject: [PATCH 1/2] compat/mingw: allow sigaction(SIGCHLD) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A future change will start using sigaction to setup a SIGCHLD signal handler. The current code uses signal(), which returns SIG_ERR (but doesn't seem to set errno) so instruct sigaction() to do the same. A new SA flag will be needed, so copy the one from Cygwinr; note that the sigacgtion() implementation that is provided won't use it, so its value is otherwise irrelevant. Signed-off-by: Carlo Marcelo Arenas Belón --- compat/mingw-posix.h | 1 + compat/mingw.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/compat/mingw-posix.h b/compat/mingw-posix.h index 88e0cf92924bd9..631a20868489be 100644 --- a/compat/mingw-posix.h +++ b/compat/mingw-posix.h @@ -96,6 +96,7 @@ struct sigaction { unsigned sa_flags; }; #define SA_RESTART 0 +#define SA_NOCLDSTOP 1 struct itimerval { struct timeval it_value, it_interval; diff --git a/compat/mingw.c b/compat/mingw.c index 8a9972a1ca19f7..5d69ae32f4b946 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2561,7 +2561,9 @@ int setitimer(int type UNUSED, struct itimerval *in, struct itimerval *out) int sigaction(int sig, struct sigaction *in, struct sigaction *out) { - if (sig != SIGALRM) + if (sig == SIGCHLD) + return -1; + else if (sig != SIGALRM) return errno = EINVAL, error("sigaction only implemented for SIGALRM"); if (out) From 81c41b43e60ca504be4c5267b335f4585f28941d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= Date: Thu, 19 Jun 2025 18:27:11 -0700 Subject: [PATCH 2/2] daemon: use sigaction() to install child_handler() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace signal() with an equivalent invocation of sigaction(), but make sure to NOT set SA_RESTART so the original code that expects to be interrupted when children complete still works as designed. This change has the added benefit of using BSD signal semantics reliably and therefore not needing the rearming call in the signal handler. Signed-off-by: Carlo Marcelo Arenas Belón --- daemon.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/daemon.c b/daemon.c index d1be61fd578949..28fc1947903860 100644 --- a/daemon.c +++ b/daemon.c @@ -915,11 +915,9 @@ static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen) static void child_handler(int signo UNUSED) { /* - * Otherwise empty handler because systemcalls will get interrupted - * upon signal receipt - * SysV needs the handler to be rearmed + * Otherwise empty handler because systemcalls should get interrupted + * upon signal receipt. */ - signal(SIGCHLD, child_handler); } static int set_reuse_addr(int sockfd) @@ -1120,6 +1118,7 @@ static void socksetup(struct string_list *listen_addr, int listen_port, struct s static int service_loop(struct socketlist *socklist) { + struct sigaction sa; struct pollfd *pfd; CALLOC_ARRAY(pfd, socklist->nr); @@ -1129,7 +1128,10 @@ static int service_loop(struct socketlist *socklist) pfd[i].events = POLLIN; } - signal(SIGCHLD, child_handler); + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = child_handler; + sigaction(SIGCHLD, &sa, NULL); for (;;) { check_dead_children();