]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Fix writing the pidfile and cleaning up a bit better.
authorRoy Marples <roy@marples.name>
Sat, 8 Feb 2014 10:36:38 +0000 (10:36 +0000)
committerRoy Marples <roy@marples.name>
Sat, 8 Feb 2014 10:36:38 +0000 (10:36 +0000)
dhcpcd.c
if-options.c
platform-linux.c

index 6a5ec71c44699d2d769c6b831bed9167caef7150..1fe57aeaf087bc37b7cf4d14c32783355dc72977 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -133,30 +133,45 @@ printf("usage: "PACKAGE"\t[-46ABbDdEGgHJKkLnpqTVw]\n"
 static void
 free_globals(void)
 {
-       int i;
-       size_t n;
        struct dhcp_opt *opt;
 
-       for (i = 0; i < ifac; i++)
-               free(ifav[i]);
-       free(ifav);
-       for (i = 0; i < ifdc; i++)
-               free(ifdv[i]);
-       free(ifdv);
+       if (ifac) {
+               for (ifac--; ifac >= 0; ifac--)
+                       free(ifav[ifac]);
+               free(ifav);
+               ifav = NULL;
+       }
+       if (ifdc) {
+               for (ifdc--; ifdc >= 0; ifdc--)
+                       free(ifdv[ifac]);
+               free(ifdv);
+               ifdv = NULL;
+       }
 
 #ifdef INET
-       for (n = 0, opt = dhcp_opts; n < dhcp_opts_len; n++, opt++)
-               free_dhcp_opt_embenc(opt);
-       free(dhcp_opts);
+       if (dhcp_opts) {
+               for (opt = dhcp_opts; dhcp_opts_len > 0;
+                   opt++, dhcp_opts_len--)
+                       free_dhcp_opt_embenc(opt);
+               free(dhcp_opts);
+               dhcp_opts = NULL;
+       }
 #endif
 #ifdef INET6
-       for (n = 0, opt = dhcp6_opts; n < dhcp6_opts_len; n++, opt++)
-               free_dhcp_opt_embenc(opt);
-       free(dhcp6_opts);
+       if (dhcp6_opts) {
+               for (opt = dhcp6_opts; dhcp6_opts_len > 0;
+                   opt++, dhcp6_opts_len--)
+                       free_dhcp_opt_embenc(opt);
+               free(dhcp6_opts);
+               dhcp6_opts = NULL;
+       }
 #endif
-       for (n = 0, opt = vivso; n < vivso_len; n++, opt++)
-               free_dhcp_opt_embenc(opt);
-       free(vivso);
+       if (vivso) {
+               for (opt = vivso; vivso_len > 0; opt++, vivso_len--)
+                       free_dhcp_opt_embenc(opt);
+               free(vivso);
+               vivso = NULL;
+       }
 }
 
 /* ARGSUSED */
@@ -185,12 +200,13 @@ handle_exit_timeout(__unused void *arg)
 }
 
 static inline int
-writepid(int fd, pid_t pid)
+write_pid(int fd, pid_t pid)
 {
 
        if (ftruncate(fd, (off_t)0) == -1)
                return -1;
-       return dprintf(fd, "%d\n", pid);
+       lseek(fd, (off_t)0, SEEK_SET);
+       return dprintf(fd, "%d\n", (int)pid);
 }
 
 /* Returns the pid of the child, otherwise 0. */
@@ -260,7 +276,7 @@ daemonise(void)
        /* Done with the fd now */
        if (pid != 0) {
                syslog(LOG_INFO, "forked to background, child pid %d", pid);
-               writepid(pidfd, pid);
+               write_pid(pidfd, pid);
                close(pidfd);
                pidfd = -1;
                options |= DHCPCD_FORKED;
@@ -1086,6 +1102,7 @@ main(int argc, char **argv)
                }
        }
 
+       control_ctx.fd = -1;
        i = 0;
        while ((opt = getopt_long(argc, argv, IF_OPTS, cf_options, &oi)) != -1)
        {
@@ -1280,7 +1297,7 @@ main(int argc, char **argv)
                        syslog(LOG_ERR, "mkdir `%s': %m", DBDIR);
 
                pidfd = open(pidfile,
-                   O_WRONLY | O_CREAT | O_NONBLOCK | O_CLOEXEC,
+                   O_WRONLY | O_CREAT | O_CLOEXEC | O_NONBLOCK,
                    0664);
                if (pidfd == -1)
                        syslog(LOG_ERR, "open `%s': %m", pidfile);
@@ -1289,9 +1306,11 @@ main(int argc, char **argv)
                         * runs on an interface */
                        if (flock(pidfd, LOCK_EX | LOCK_NB) == -1) {
                                syslog(LOG_ERR, "flock `%s': %m", pidfile);
+                               close(pidfd);
+                               pidfd = -1;
                                goto exit_failure;
                        }
-                       writepid(pidfd, getpid());
+                       write_pid(pidfd, getpid());
                }
        }
 
@@ -1361,8 +1380,8 @@ main(int argc, char **argv)
                }
        }
 
-       if (options & DHCPCD_BACKGROUND)
-               daemonise();
+       if (options & DHCPCD_BACKGROUND && daemonise())
+               goto exit_success;
 
        opt = 0;
        TAILQ_FOREACH(ifp, ifaces, next) {
@@ -1428,16 +1447,27 @@ exit_failure:
        i = EXIT_FAILURE;
 
 exit1:
+       /* Free memory and close fd's.
+        * We also set global variables back to their initial variables
+        * so we work nicely in a threads based environment as opposed to
+        * the normal process one. */
        if (ifaces) {
                while ((ifp = TAILQ_FIRST(ifaces))) {
                        TAILQ_REMOVE(ifaces, ifp, next);
                        free_interface(ifp);
                }
                free(ifaces);
+               ifaces = NULL;
        }
 
-       free(duid);
-       free_options(if_options);
+       if (duid) {
+               free(duid);
+               duid = NULL;
+       }
+       if (if_options) {
+               free_options(if_options);
+               if_options = NULL;
+       }
        free_globals();
        restore_kernel_ra();
        ipv4_free(NULL);
@@ -1450,13 +1480,16 @@ exit1:
        if (pidfd > -1) {
                if (options & DHCPCD_MASTER) {
                        if (control_stop(&control_ctx) == -1)
-                               syslog(LOG_ERR, "control_stop: %m");
+                               syslog(LOG_ERR, "control_stop: %m:");
                }
                close(pidfd);
                unlink(pidfile);
                pidfd = -1;
        }
-       free(pidfile);
+       if (pidfile) {
+               free(pidfile);
+               pidfile = NULL;
+       }
 
        if (options & DHCPCD_STARTED && !(options & DHCPCD_FORKED))
                syslog(LOG_INFO, "exited");
index 3c1ddabcad83cb4da94ba8d74be304c01d41e750..f6b32e978008797eb65ca78a54566c5d12341101 100644 (file)
@@ -2041,30 +2041,30 @@ free_options(struct if_options *ifo)
                free(ifo->blacklist);
                free(ifo->fallback);
 
-               for (i = 0, opt = ifo->dhcp_override;
-                   i < ifo->dhcp_override_len;
-                   i++, opt++)
+               for (opt = ifo->dhcp_override;
+                   ifo->dhcp_override_len > 0;
+                   opt++, ifo->dhcp_override_len--)
                        free_dhcp_opt_embenc(opt);
                free(ifo->dhcp_override);
-               for (i = 0, opt = ifo->dhcp6_override;
-                   i < ifo->dhcp6_override_len;
-                   i++, opt++)
+               for (opt = ifo->dhcp6_override;
+                   ifo->dhcp6_override_len > 0;
+                   opt++, ifo->dhcp6_override_len--)
                        free_dhcp_opt_embenc(opt);
                free(ifo->dhcp6_override);
-               for (i = 0, vo = ifo->vivco;
-                   i < ifo->vivco_len;
-                   i++, vo++)
+               for (vo = ifo->vivco;
+                   ifo->vivco_len > 0;
+                   vo++, ifo->vivco_len--)
                        free(vo->data);
                free(ifo->vivco);
-               for (i = 0, opt = ifo->vivso_override;
-                   i < ifo->vivso_override_len;
-                   i++, opt++)
+               for (opt = ifo->vivso_override;
+                   ifo->vivso_override_len > 0;
+                   opt++, ifo->vivso_override_len--)
                        free_dhcp_opt_embenc(opt);
                free(ifo->vivso_override);
 
 #ifdef INET6
-               for (i = 0; i < ifo->ia_len; i++)
-                       free(ifo->ia[i].sla);
+               for (; ifo->ia_len > 0; ifo->ia_len--)
+                       free(ifo->ia[ifo->ia_len - 1].sla);
 #endif
                free(ifo->ia);
 
index 6fe470c6de183ff3b4576c60d6decf0e2e7a2b81..877e9887e27569d0d63ef61e96517c48a6a9137e 100644 (file)
@@ -146,18 +146,19 @@ restore_kernel_ra(void)
        if (options & DHCPCD_FORKED)
                return;
 
-       for (nrestore--; nrestore >= 0; nrestore--) {
+       for (; nrestore > 0; nrestore--) {
                if (!(options & DHCPCD_FORKED)) {
                        syslog(LOG_INFO, "%s: restoring Kernel IPv6 RA support",
-                           restore[nrestore]);
+                           restore[nrestore - 1]);
                        snprintf(path, sizeof(path), "%s/%s/accept_ra",
-                           prefix, restore[nrestore]);
+                           prefix, restore[nrestore - 1]);
                        if (write_path(path, "1") == -1 && errno != ENOENT)
                            syslog(LOG_ERR, "write_path: %s: %m", path);
                }
-               free(restore[nrestore]);
+               free(restore[nrestore - 1]);
        }
        free(restore);
+       restore = NULL;
 }
 
 int