]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Replace the signal clear with a pipe so child can notify parent when to exit.
authorRoy Marples <roy@marples.name>
Tue, 27 May 2008 19:06:48 +0000 (19:06 +0000)
committerRoy Marples <roy@marples.name>
Tue, 27 May 2008 19:06:48 +0000 (19:06 +0000)
client.c
signals.c
signals.h

index 9342a43b6cc0b3d9780cc26c42129ff470ff9808..70f7a3ab2e730da422e64dc4c0290d0031c1cd56 100644 (file)
--- a/client.c
+++ b/client.c
@@ -145,6 +145,9 @@ daemonise(struct if_state *state, const struct options *options)
 #ifdef THERE_IS_NO_FORK
        char **argv;
        int i;
+#else
+       char buf = '\0';
+       int sidpipe[2];
 #endif
 
        if (state->options & DHCPCD_DAEMONISED ||
@@ -155,6 +158,12 @@ daemonise(struct if_state *state, const struct options *options)
        sigprocmask(SIG_SETMASK, &full, &old);
 
 #ifndef THERE_IS_NO_FORK
+       /* Setup a signal pipe so parent knows when to exit. */
+       if (pipe(sidpipe) == -1) {
+               logger(LOG_ERR,"pipe: %s", strerror(errno));
+               return -1;
+       }
+
        logger(LOG_DEBUG, "forking to background");
        switch (pid = fork()) {
                case -1:
@@ -163,13 +172,17 @@ daemonise(struct if_state *state, const struct options *options)
                        /* NOTREACHED */
                case 0:
                        setsid();
+                       /* Notify parent it's safe to exit as we've detached. */
+                       write(sidpipe[1], &buf, 1);
                        close_fds();
-                       /* Clear pending signals */
-                       signal_clear();
                        break;
                default:
                        /* Reset signals as we're the parent about to exit. */
                        signal_reset();
+                       /* Wait for child to detach */
+                       close(sidpipe[1]);
+                       read(sidpipe[0], &buf, 1);
+                       close(sidpipe[0]);
                        break;
        }
 #else
index c0b60e313c2b70b7eeba996c00248942a90c2447..4559749caf255b397be43591b3321268ccd75d48 100644 (file)
--- a/signals.c
+++ b/signals.c
@@ -134,38 +134,29 @@ signal_init(void)
 }
 
 static int
-signal_handle(void (*func)(int), int restore)
+signal_handle(void (*func)(int))
 {
        unsigned int i;
-       struct sigaction sa, sa_old;
+       struct sigaction sa;
 
        memset(&sa, 0, sizeof(sa));
        sa.sa_handler = func;
        sigemptyset(&sa.sa_mask);
 
-       for (i = 0; i < sizeof(handle_sigs) / sizeof(handle_sigs[0]); i++) {
-               if (sigaction(handle_sigs[i], &sa, &sa_old) == -1)
+       for (i = 0; i < sizeof(handle_sigs) / sizeof(handle_sigs[0]); i++)
+               if (sigaction(handle_sigs[i], &sa, NULL) == -1)
                        return -1;
-               if (restore && sigaction(handle_sigs[i], &sa_old, NULL) == -1)
-                               return -1;
-       }
        return 0;
 }
 
 int
 signal_setup(void)
 {
-       return signal_handle(signal_handler, 0);
+       return signal_handle(signal_handler);
 }
 
 int
 signal_reset(void)
 {
-       return signal_handle(SIG_DFL, 0);
-}
-
-int
-signal_clear(void) 
-{
-       return signal_handle(SIG_IGN, 1);
+       return signal_handle(SIG_DFL);
 }
index 6101b7280e8558f93490f313399a8fc225cb8da1..948099d2a8557569900a7bad36f99f634882c858 100644 (file)
--- a/signals.h
+++ b/signals.h
@@ -33,7 +33,6 @@
 int signal_init(void);
 int signal_setup(void);
 int signal_reset(void);
-int signal_clear(void);
 int signal_fd(void);
 int signal_exists(const struct pollfd *);
 int signal_read(struct pollfd *);