Mercurial > hg > dhcpcd
changeset 1874:559e02266deb draft
Avoid a potential malloc when handling signals.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Tue, 26 Mar 2013 08:51:34 +0000 |
| parents | daaec5a8be6b |
| children | 7d432c417d3c |
| files | dhcpcd.c eloop.c eloop.h |
| diffstat | 3 files changed, 37 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/dhcpcd.c Tue Mar 26 06:39:58 2013 +0000 +++ b/dhcpcd.c Tue Mar 26 08:51:34 2013 +0000 @@ -666,6 +666,16 @@ reconf_reboot(1, ifc, ifv, 0); } +static void +sig_reconf(_unused void *arg) +{ + struct interface *ifp; + + TAILQ_FOREACH(ifp, ifaces, next) { + ipv4_applyaddr(ifp); + } +} + void handle_signal(int sig) { @@ -685,7 +695,7 @@ /* We shouldn't modify any variables in the signal * handler, so simply add reboot function to the queue * for an immediate callout. */ - eloop_timeout_add_sec(0, sig_reboot, NULL); + eloop_timeout_add_now(sig_reboot, NULL); return; case SIGHUP: syslog(LOG_INFO, "received SIGHUP, releasing"); @@ -693,9 +703,7 @@ break; case SIGUSR1: syslog(LOG_INFO, "received SIGUSR, reconfiguring"); - TAILQ_FOREACH(ifp, ifaces, next) { - ipv4_applyaddr(ifp); - } + eloop_timeout_add_now(sig_reconf, NULL); return; case SIGPIPE: syslog(LOG_WARNING, "received SIGPIPE");
--- a/eloop.c Tue Mar 26 06:39:58 2013 +0000 +++ b/eloop.c Tue Mar 26 08:51:34 2013 +0000 @@ -68,6 +68,9 @@ static struct timeout_head free_timeouts = TAILQ_HEAD_INITIALIZER(free_timeouts); +static void (*volatile timeout0)(void *); +static void *volatile timeout0_arg; + static struct pollfd *fds; static size_t fds_len; @@ -215,6 +218,20 @@ return eloop_q_timeout_add_tv(queue, &tv, callback, arg); } +int +eloop_timeout_add_now(void (*callback)(void *), void *arg) +{ + + if (timeout0 != NULL) { + syslog(LOG_WARNING, "%s: timeout0 already set", __func__); + return eloop_q_timeout_add_sec(0, 0, callback, arg); + } + + timeout0 = callback; + timeout0_arg = arg; + return 0; +} + /* This deletes all timeouts for the interface EXCEPT for ones with the * callbacks given. Handy for deleting everything apart from the expire * timeout. */ @@ -314,9 +331,16 @@ struct timeout *t; struct timeval tv; struct timespec ts, *tsp; + void (*t0)(void *); for (;;) { /* Run all timeouts first */ + if (timeout0) { + t0 = timeout0; + timeout0 = NULL; + t0(timeout0_arg); + continue; + } if ((t = TAILQ_FIRST(&timeouts))) { get_monotonic(&now); if (timercmp(&now, &t->when, >)) {
--- a/eloop.h Tue Mar 26 06:39:58 2013 +0000 +++ b/eloop.h Tue Mar 26 08:51:34 2013 +0000 @@ -49,6 +49,7 @@ int eloop_q_timeout_add_sec(int queue, time_t, void (*)(void *), void *); int eloop_q_timeout_add_tv(int queue, const struct timeval *, void (*)(void *), void *); +int eloop_timeout_add_now(void (*)(void *), void *); void eloop_q_timeout_delete(int, void (*)(void *), void *); void eloop_q_timeouts_delete(int, void *, void (*)(void *), ...); void eloop_init(void);
