From: Roy Marples Date: Tue, 27 May 2008 19:06:48 +0000 (+0000) Subject: Replace the signal clear with a pipe so child can notify parent when to exit. X-Git-Tag: v4.0.2~320 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=caecf62c79ac0cf15a8b02f365c4976f28621606;p=thirdparty%2Fdhcpcd.git Replace the signal clear with a pipe so child can notify parent when to exit. --- diff --git a/client.c b/client.c index 9342a43b..70f7a3ab 100644 --- 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 diff --git a/signals.c b/signals.c index c0b60e31..4559749c 100644 --- 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); } diff --git a/signals.h b/signals.h index 6101b728..948099d2 100644 --- 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 *);