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

Reply via email to