Mercurial > hg > dhcpcd
changeset 1854:c6a5468314d3 draft
Restore our signal pipe so that we process signals in our event loop
as we use a lot of functions which are not safe according to signal(7).
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Mon, 18 Feb 2013 15:40:56 +0000 |
| parents | e6eebb123e36 |
| children | 407f259434ff |
| files | dhcpcd.c signals.c signals.h |
| diffstat | 3 files changed, 45 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/dhcpcd.c Mon Feb 18 10:37:02 2013 +0000 +++ b/dhcpcd.c Mon Feb 18 15:40:56 2013 +0000 @@ -1130,7 +1130,7 @@ * when we're testing fd's. * This allows us to ensure a consistent state is maintained * regardless of when we are interrupted .*/ - if (signal_setup(handle_signal, &dhcpcd_sigset) == -1) { + if (signal_init(handle_signal, &dhcpcd_sigset) == -1) { syslog(LOG_ERR, "signal_setup: %m"); exit(EXIT_FAILURE); }
--- a/signals.c Mon Feb 18 10:37:02 2013 +0000 +++ b/signals.c Mon Feb 18 15:40:56 2013 +0000 @@ -32,8 +32,12 @@ #include <unistd.h> #include "common.h" +#include "eloop.h" #include "signals.h" +static int signal_pipe[2]; +static void (*signal_callback)(int); + const int handle_sigs[] = { SIGALRM, SIGHUP, @@ -44,6 +48,31 @@ 0 }; +static void +signal_handler(int sig) +{ + int serrno = errno; + + if (write(signal_pipe[1], &sig, sizeof(sig)) != sizeof(sig)) + syslog(LOG_ERR, "%s: write: %m", __func__); + errno = serrno; +} + +static void +signal_read(_unused void *arg) +{ + int sig = -1; + char buf[16]; + ssize_t bytes; + + memset(buf, 0, sizeof(buf)); + bytes = read(signal_pipe[0], buf, sizeof(buf)); + if (signal_callback && bytes >= 0 && (size_t)bytes >= sizeof(sig)) { + memcpy(&sig, buf, sizeof(sig)); + signal_callback(sig); + } +} + static int signal_handle(void (*func)(int), sigset_t *oldset) { @@ -70,15 +99,21 @@ } int -signal_setup(void (*func)(int), sigset_t *oldset) +signal_init(void (*func)(int), sigset_t *oldset) { - return signal_handle(func, oldset); -} + if (pipe(signal_pipe) == -1) + return -1; + if (set_nonblock(signal_pipe[0]) == -1) + return -1; + if (set_cloexec(signal_pipe[0]) == -1 || + set_cloexec(signal_pipe[1] == -1)) + return -1; -int -signal_reset(void) -{ - - return signal_handle(SIG_DFL, NULL); + /* Because functions we need to reboot/reconf out interfaces + * are not async signal safe, we need to setup a signal pipe + * so that the actual handler is executed in our event loop. */ + signal_callback = func; + eloop_event_add(signal_pipe[0], signal_read, NULL); + return signal_handle(signal_handler, oldset); }
--- a/signals.h Mon Feb 18 10:37:02 2013 +0000 +++ b/signals.h Mon Feb 18 15:40:56 2013 +0000 @@ -30,10 +30,6 @@ extern const int handle_sigs[]; -int signal_init(void); -int signal_setup(void (*)(int), sigset_t *); -int signal_reset(void); -int signal_read(void); -int signal_block(int); +int signal_init(void (*)(int), sigset_t *); #endif
