#ifdef THERE_IS_NO_FORK
char **argv;
int i;
+#else
+ char buf = '\0';
+ int sidpipe[2];
#endif
if (state->options & DHCPCD_DAEMONISED ||
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:
/* 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
}
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);
}