Module Name: src
Committed By: roy
Date: Thu Oct 19 11:26:52 UTC 2023
Modified Files:
src/external/bsd/dhcpcd/dist/src: dhcpcd.c privsep.c script.c
Log Message:
Sync with dhcpcd-10.0.4
To generate a diff of this commit:
cvs rdiff -u -r1.52 -r1.53 src/external/bsd/dhcpcd/dist/src/dhcpcd.c
cvs rdiff -u -r1.16 -r1.17 src/external/bsd/dhcpcd/dist/src/privsep.c \
src/external/bsd/dhcpcd/dist/src/script.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.c
diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.52 src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.53
--- src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.52 Fri Oct 6 08:49:42 2023
+++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c Thu Oct 19 11:26:52 2023
@@ -329,6 +329,36 @@ dhcpcd_ipwaited(struct dhcpcd_ctx *ctx)
return 1;
}
+#ifndef THERE_IS_NO_FORK
+void
+dhcpcd_daemonised(struct dhcpcd_ctx *ctx)
+{
+ unsigned int logopts = loggetopts();
+
+ /*
+ * Stop writing to stderr.
+ * On the happy path, only the manager process writes to stderr,
+ * so this just stops wasting fprintf calls to nowhere.
+ * All other calls - ie errors in privsep processes or script output,
+ * will error when printing.
+ * If we *really* want to fix that, then we need to suck
+ * stderr/stdout in the manager process and either discard it or pass
+ * it to the launcher process and then to stderr.
+ */
+ logopts &= ~LOGERR_ERR;
+ logsetopts(logopts);
+
+ /*
+ * We need to do something with stdout/stderr to avoid SIGPIPE
+ * We know that stdin is already mapped to /dev/null
+ */
+ dup2(STDIN_FILENO, STDOUT_FILENO);
+ dup2(STDIN_FILENO, STDERR_FILENO);
+
+ ctx->options |= DHCPCD_DAEMONISED;
+}
+#endif
+
/* Returns the pid of the child, otherwise 0. */
void
dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
@@ -363,6 +393,13 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
if (!(logopts & LOGERR_QUIET) && ctx->stderr_valid)
(void)fprintf(stderr,
"forked to background, child pid %d\n", getpid());
+
+#ifdef PRIVSEP
+ ps_daemonised(ctx);
+#else
+ dhcpcd_daemonised(ctx);
+#endif
+
i = EXIT_SUCCESS;
if (write(ctx->fork_fd, &i, sizeof(i)) == -1)
logerr("write");
@@ -370,19 +407,6 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
eloop_event_delete(ctx->eloop, ctx->fork_fd);
close(ctx->fork_fd);
ctx->fork_fd = -1;
-
- /*
- * Stop writing to stderr.
- * On the happy path, only the manager process writes to stderr,
- * so this just stops wasting fprintf calls to nowhere.
- * All other calls - ie errors in privsep processes or script output,
- * will error when printing.
- * If we *really* want to fix that, then we need to suck
- * stderr/stdout in the manager process and either disacrd it or pass
- * it to the launcher process and then to stderr.
- */
- logopts &= ~LOGERR_ERR;
- logsetopts(logopts);
#endif
}
@@ -1869,6 +1893,22 @@ dhcpcd_pidfile_timeout(void *arg)
dhcpcd_pidfile_timeout, ctx);
}
+static int dup_null(int fd)
+{
+ int fd_null = open(_PATH_DEVNULL, O_WRONLY);
+ int err;
+
+ if (fd_null == -1) {
+ logwarn("open %s", _PATH_DEVNULL);
+ return -1;
+ }
+
+ if ((err = dup2(fd_null, fd)) == -1)
+ logwarn("dup2 %d", fd);
+ close(fd_null);
+ return err;
+}
+
int
main(int argc, char **argv, char **envp)
{
@@ -1972,6 +2012,15 @@ main(int argc, char **argv, char **envp)
ctx.stdout_valid = fcntl(STDOUT_FILENO, F_GETFD) != -1;
ctx.stderr_valid = fcntl(STDERR_FILENO, F_GETFD) != -1;
+ /* Even we if we don't have input/outputs, we need to
+ * ensure they are setup for shells. */
+ if (!ctx.stdin_valid)
+ dup_null(STDIN_FILENO);
+ if (!ctx.stdout_valid)
+ dup_null(STDOUT_FILENO);
+ if (!ctx.stderr_valid)
+ dup_null(STDERR_FILENO);
+
logopts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID;
if (ctx.stderr_valid)
logopts |= LOGERR_ERR;
@@ -2341,8 +2390,10 @@ printpidfile:
}
loginfox(PACKAGE "-" VERSION " starting");
- if (ctx.stdin_valid && freopen(_PATH_DEVNULL, "w", stdin) == NULL)
- logwarn("freopen stdin");
+
+ // We don't need stdin past this point
+ if (ctx.stdin_valid)
+ dup_null(STDIN_FILENO);
#if defined(USE_SIGNALS) && !defined(THERE_IS_NO_FORK)
if (!(ctx.options & DHCPCD_DAEMONISE))
@@ -2385,10 +2436,9 @@ printpidfile:
logerr("dup2");
close(stderr_fd[0]);
close(stderr_fd[1]);
- } else if (ctx.stdout_valid) {
- if (freopen(_PATH_DEVNULL, "w", stdout) == NULL)
- logerr("freopen stdout");
- }
+ } else if (ctx.stdout_valid)
+ dup_null(STDOUT_FILENO);
+
if (setsid() == -1) {
logerr("%s: setsid", __func__);
goto exit_failure;
Index: src/external/bsd/dhcpcd/dist/src/privsep.c
diff -u src/external/bsd/dhcpcd/dist/src/privsep.c:1.16 src/external/bsd/dhcpcd/dist/src/privsep.c:1.17
--- src/external/bsd/dhcpcd/dist/src/privsep.c:1.16 Fri Oct 6 08:49:42 2023
+++ src/external/bsd/dhcpcd/dist/src/privsep.c Thu Oct 19 11:26:52 2023
@@ -1100,6 +1100,26 @@ ps_recvmsg(int rfd, unsigned short event
}
ssize_t
+ps_daemonised(struct dhcpcd_ctx *ctx)
+{
+ struct ps_process *psp;
+ ssize_t err = 0;
+
+ dhcpcd_daemonised(ctx);
+
+ /* Echo the message to all processes */
+ TAILQ_FOREACH(psp, &ctx->ps_processes, next) {
+ if (psp->psp_pid == getpid())
+ continue;
+ if (ps_sendcmd(psp->psp_ctx, psp->psp_fd, PS_DAEMONISED,
+ 0, NULL, 0) == -1)
+ err = -1;
+ }
+
+ return err;
+}
+
+ssize_t
ps_recvpsmsg(struct dhcpcd_ctx *ctx, int fd, unsigned short events,
ssize_t (*callback)(void *, struct ps_msghdr *, struct msghdr *),
void *cbctx)
@@ -1131,6 +1151,9 @@ ps_recvpsmsg(struct dhcpcd_ctx *ctx, int
if (psm.psm_hdr.ps_cmd == PS_STOP) {
stop = true;
len = 0;
+ } else if (psm.psm_hdr.ps_cmd == PS_DAEMONISED) {
+ ps_daemonised(ctx);
+ return 0;
}
}
Index: src/external/bsd/dhcpcd/dist/src/script.c
diff -u src/external/bsd/dhcpcd/dist/src/script.c:1.16 src/external/bsd/dhcpcd/dist/src/script.c:1.17
--- src/external/bsd/dhcpcd/dist/src/script.c:1.16 Wed Jul 19 13:53:03 2023
+++ src/external/bsd/dhcpcd/dist/src/script.c Thu Oct 19 11:26:52 2023
@@ -682,33 +682,42 @@ send_interface(struct fd_list *fd, const
}
static int
+script_status(const char *script, int status)
+{
+
+ if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status))
+ logerrx("%s: %s: WEXITSTATUS %d",
+ __func__, script, WEXITSTATUS(status));
+ } else if (WIFSIGNALED(status))
+ logerrx("%s: %s: %s",
+ __func__, script, strsignal(WTERMSIG(status)));
+
+ return WEXITSTATUS(status);
+}
+
+static int
script_run(struct dhcpcd_ctx *ctx, char **argv)
{
pid_t pid;
- int status = 0;
+ int status;
pid = script_exec(argv, ctx->script_env);
- if (pid == -1)
+ if (pid == -1) {
logerr("%s: %s", __func__, argv[0]);
- else if (pid != 0) {
- /* Wait for the script to finish */
- while (waitpid(pid, &status, 0) == -1) {
- if (errno != EINTR) {
- logerr("%s: waitpid", __func__);
- status = 0;
- break;
- }
+ return -1;
+ } else if (pid == 0)
+ return 0;
+
+ /* Wait for the script to finish */
+ while (waitpid(pid, &status, 0) == -1) {
+ if (errno != EINTR) {
+ logerr("%s: waitpid", __func__);
+ status = 0;
+ break;
}
- if (WIFEXITED(status)) {
- if (WEXITSTATUS(status))
- logerrx("%s: %s: WEXITSTATUS %d",
- __func__, argv[0], WEXITSTATUS(status));
- } else if (WIFSIGNALED(status))
- logerrx("%s: %s: %s",
- __func__, argv[0], strsignal(WTERMSIG(status)));
}
-
- return WEXITSTATUS(status);
+ return script_status(argv[0], status);
}
int
@@ -762,10 +771,14 @@ script_runreason(const struct interface
logdebugx("%s: executing: %s %s", ifp->name, argv[0], reason);
#ifdef PRIVSEP
- if (ctx->options & DHCPCD_PRIVSEP) {
- if (ps_root_script(ctx,
- ctx->script_buf, (size_t)buflen) == -1)
+ if (IN_PRIVSEP(ctx)) {
+ ssize_t err;
+
+ err = ps_root_script(ctx, ctx->script_buf, (size_t)buflen);
+ if (err == -1)
logerr(__func__);
+ else
+ script_status(ctx->script, (int)err);
goto send_listeners;
}
#endif