From 637459052b01632ce2c4e9e36c93509f65fb4788 Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Sun, 11 May 2014 14:52:49 +0200 Subject: [PATCH] use double-fork for notification processes --- src/wall-notify.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/wall-notify.c b/src/wall-notify.c index 343f3d0..13e7829 100644 --- a/src/wall-notify.c +++ b/src/wall-notify.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #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]; -- 2.45.2