changeset 1852:88c0d789333e draft

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.
author Roy Marples <roy@marples.name>
date Mon, 18 Feb 2013 10:35:47 +0000
parents 19767d5480d4
children e6eebb123e36
files dhcpcd.c
diffstat 1 files changed, 33 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/dhcpcd.c	Mon Feb 18 08:13:43 2013 +0000
+++ b/dhcpcd.c	Mon Feb 18 10:35:47 2013 +0000
@@ -649,12 +649,39 @@
 	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 @@
 		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");