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 */
}
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. */
/* 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;
}
}
+ control_ctx.fd = -1;
i = 0;
while ((opt = getopt_long(argc, argv, IF_OPTS, cf_options, &oi)) != -1)
{
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);
* 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());
}
}
}
}
- if (options & DHCPCD_BACKGROUND)
- daemonise();
+ if (options & DHCPCD_BACKGROUND && daemonise())
+ goto exit_success;
opt = 0;
TAILQ_FOREACH(ifp, ifaces, next) {
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);
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");
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);
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