activate: improve SIGCHLD handler
* Don't lose children exit codes
* Don't receive notification when child processes stop
Eliminates annoying "Child died"-messages:
$ ./systemd-socket-activate -l 2000 --inetd -a cat
^Z
[1]+ Stopped ./systemd-socket-activate -l 2000 --inetd -a cat
$ bg %1
[1]+ ./systemd-socket-activate -l 2000 --inetd -a cat &
Child 15657 died with code 20
$ ps u 15657
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
ubuntu 15657 0.0 0.0 4540 680 pts/2 S 00:34 0:00 cat
* Don't fail to reap some zombie children
Fixes
$ ./systemd-socket-activate -l 2000 --inetd -a cat &
$ for i in {1..1000}; do echo a | nc localhost 2000 & done
$ ps f
...
18235 pts/2 Ss 0:01 -bash
15849 pts/2 S 0:00 \_ ./systemd-socket-activate -l 2000 --inetd
-a cat
16081 pts/2 Z 0:00 | \_ [cat] <defunct>
16381 pts/2 Z 0:00 | \_ [cat] <defunct>
and many more zombies
...
This commit is contained in:
+18
-6
@@ -316,19 +316,31 @@ static int do_accept(const char* name, char **argv, char **envp, int fd) {
|
||||
}
|
||||
|
||||
/* SIGCHLD handler. */
|
||||
static void sigchld_hdl(int sig, siginfo_t *t, void *data) {
|
||||
static void sigchld_hdl(int sig) {
|
||||
PROTECT_ERRNO;
|
||||
|
||||
log_info("Child %d died with code %d", t->si_pid, t->si_status);
|
||||
for (;;) {
|
||||
siginfo_t si;
|
||||
int r;
|
||||
|
||||
/* Wait for a dead child. */
|
||||
(void) waitpid(t->si_pid, NULL, 0);
|
||||
si.si_pid = 0;
|
||||
r = waitid(P_ALL, 0, &si, WEXITED|WNOHANG);
|
||||
if (r < 0) {
|
||||
if (errno != ECHILD)
|
||||
log_error_errno(errno, "Failed to reap children: %m");
|
||||
return;
|
||||
}
|
||||
if (si.si_pid == 0)
|
||||
return;
|
||||
|
||||
log_info("Child %d died with code %d", si.si_pid, si.si_status);
|
||||
}
|
||||
}
|
||||
|
||||
static int install_chld_handler(void) {
|
||||
static const struct sigaction act = {
|
||||
.sa_flags = SA_SIGINFO,
|
||||
.sa_sigaction = sigchld_hdl,
|
||||
.sa_flags = SA_NOCLDSTOP,
|
||||
.sa_handler = sigchld_hdl,
|
||||
};
|
||||
|
||||
int r;
|
||||
|
||||
Reference in New Issue
Block a user