From: Roy Marples Date: Mon, 18 Feb 2013 10:35:47 +0000 (+0000) Subject: Move the signal reboot code into it's own function which is fired by X-Git-Tag: v5.99.6~62 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a54116c1c68e8ff8ff805b541fc19efbd0658a3d;p=thirdparty%2Fdhcpcd.git Move the signal reboot code into it's own function which is fired by and eloop timeout of 0 seconds. We do this because we shouldn't modify variables in a signal handler. --- diff --git a/dhcpcd.c b/dhcpcd.c index 50a455e5..69898c38 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -649,12 +649,39 @@ reconf_reboot(int action, int argc, char **argv, int oi) sort_interfaces(); } +static void +sig_reboot(_unused void *arg) +{ + struct if_options *ifo; + int i; + + for (i = 0; i < ifac; i++) + free(ifav[i]); + free(ifav); + ifav = NULL; + ifac = 0; + for (i = 0; i < ifdc; i++) + free(ifdv[i]); + free(ifdv); + ifdc = 0; + ifdv = NULL; + ifo = read_config(cffile, NULL, NULL, NULL); + add_options(ifo, margc, margv); + /* We need to preserve these two options. */ + if (options & DHCPCD_MASTER) + ifo->options |= DHCPCD_MASTER; + if (options & DHCPCD_DAEMONISED) + ifo->options |= DHCPCD_DAEMONISED; + options = ifo->options; + free_options(ifo); + reconf_reboot(1, ifc, ifv, 0); +} + void handle_signal(int sig) { struct interface *ifp; - struct if_options *ifo; - int do_release, i; + int do_release; do_release = 0; switch (sig) { @@ -666,26 +693,10 @@ handle_signal(int sig) break; case SIGALRM: syslog(LOG_INFO, "received SIGALRM, rebinding"); - for (i = 0; i < ifac; i++) - free(ifav[i]); - free(ifav); - ifav = NULL; - ifac = 0; - for (i = 0; i < ifdc; i++) - free(ifdv[i]); - free(ifdv); - ifdc = 0; - ifdv = NULL; - ifo = read_config(cffile, NULL, NULL, NULL); - add_options(ifo, margc, margv); - /* We need to preserve these two options. */ - if (options & DHCPCD_MASTER) - ifo->options |= DHCPCD_MASTER; - if (options & DHCPCD_DAEMONISED) - ifo->options |= DHCPCD_DAEMONISED; - options = ifo->options; - free_options(ifo); - reconf_reboot(1, ifc, ifv, 0); + /* 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); return; case SIGHUP: syslog(LOG_INFO, "received SIGHUP, releasing");