]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
activate: improve SIGCHLD handler 2961/head
authorEvgeny Vereshchagin <evvers@ya.ru>
Tue, 5 Apr 2016 00:27:15 +0000 (00:27 +0000)
committerEvgeny Vereshchagin <evvers@ya.ru>
Tue, 5 Apr 2016 14:34:04 +0000 (14:34 +0000)
* 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
...

src/activate/activate.c

index 8ac8dd8e727f459f8da42637d8fac2cdbb086e87..a0cfc22000a395e695314caeee2ccd5eeb584ea3 100644 (file)
@@ -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;