]> ruderich.org/simon Gitweb - wall-notify/wall-notify.git/commitdiff
use double-fork for notification processes
authorSimon Ruderich <simon@ruderich.org>
Sun, 11 May 2014 12:52:49 +0000 (14:52 +0200)
committerSimon Ruderich <simon@ruderich.org>
Sun, 11 May 2014 12:52:49 +0000 (14:52 +0200)
src/wall-notify.c

index 343f3d0ff37bfbb5a6798ee70158dbbed0cceb4a..13e7829926f04708708e084d1dd147e895f864ff 100644 (file)
@@ -33,6 +33,7 @@
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <unistd.h>
 
 #ifdef USE_UTEMPTER
@@ -60,9 +61,6 @@ static void setup_signals(void) {
     sigaction(SIGQUIT, &action, NULL);
     sigaction(SIGUSR1, &action, NULL);
     sigaction(SIGUSR2, &action, NULL);
-
-    /* Collect zombies automatically without having to call waitpid(2). */
-    signal(SIGCHLD, SIG_IGN);
 }
 
 static int open_tty(void) {
@@ -225,9 +223,21 @@ static void pass_buffer_to_program(const char *buffer, size_t length, char **arg
         }
         close(fds[0]);
 
-        execvp(argv[0], argv);
-        perror("execvp");
-        exit(EXIT_FAILURE);
+        /* Double fork so `wall-notify` doesn't have to wait for the
+         * notification process to terminate. We can't just use
+         * signal(SIGCHLD, SIG_IGN); because utempter on at least FreeBSD
+         * doesn't work if SIGCHLD is ignored. */
+        pid = fork();
+        if (pid < 0) {
+            perror("fork");
+            exit(EXIT_FAILURE);
+        } else if (pid == 0) {
+            execvp(argv[0], argv);
+            perror("execvp");
+            exit(EXIT_FAILURE);
+        }
+
+        exit(EXIT_SUCCESS);
     }
     /* father */
 
@@ -239,6 +249,10 @@ static void pass_buffer_to_program(const char *buffer, size_t length, char **arg
 out:
     close(fds[0]); /* read side */
     fclose(fh);
+
+    if (waitpid(pid, NULL, 0) < 0) {
+        perror("waitpid");
+    }
 }
 static void handle_wall(int fd, char **argv) {
     char buffer[4096];