server: Use a temporary SIGCHLD handler to catch afs init failures.
authorAndre Noll <maan@systemlinux.org>
Sat, 21 Mar 2009 16:46:43 +0000 (17:46 +0100)
committerAndre Noll <maan@systemlinux.org>
Sat, 21 Mar 2009 16:46:43 +0000 (17:46 +0100)
If afs dies immediately on startup (because of dirty tables) para_server
would not notice as the SIGCHLD handler is being intalled after the
call to afs_init().

server.c

index 9c06991..4415cdc 100644 (file)
--- a/server.c
+++ b/server.c
@@ -467,6 +467,12 @@ static int init_afs(void)
        return afs_server_socket[0];
 }
 
+__noreturn static void tmp_sigchld_handler(__a_unused int s)
+{
+       PARA_EMERG_LOG("caught early SIGCHLD\n");
+       exit(EXIT_FAILURE);
+}
+
 static void server_init(int argc, char **argv)
 {
        struct server_cmdline_parser_params params = {
@@ -509,6 +515,15 @@ static void server_init(int argc, char **argv)
                PARA_EMERG_LOG("failed to ignore SIGUSR1\n");
                exit(EXIT_FAILURE);
        }
+       /*
+        * We have to install a SIGCHLD handler before the afs process is being
+        * forked off. Otherwise, para_server does not notice if afs dies before
+        * the SIGCHLD handler has been installed by init_signal_task() below.
+        */
+       if (signal(SIGCHLD, tmp_sigchld_handler) == SIG_ERR) {
+               PARA_EMERG_LOG("failed to install temporary SIGCHLD handler\n");
+               exit(EXIT_FAILURE);
+       }
        PARA_NOTICE_LOG("initializing the audio file selector\n");
        afs_socket = init_afs();
        init_signal_task();