summaryrefslogtreecommitdiffstats
path: root/src/dhcpcd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-09-06 02:41:08 +0100
committerRoy Marples <roy@marples.name>2020-09-06 02:41:08 +0100
commit71b878695ef0557a036fee35997e52cd1f3d2aea (patch)
treeb9ebe3c4510a00663e8b6993c39c3a35b7bafde1 /src/dhcpcd.c
parente80f2a5aeaf2e249ca6b6a10090f64c69ea99719 (diff)
downloaddhcpcd-71b878695ef0557a036fee35997e52cd1f3d2aea.tar.xz
dhcpcd: Redirect stdout/stderr to the launcher stderr descriptor
This actually make life really simple! We no longer need to redirect stdout/stderr to /dev/null for privsep and any script output is now captured again - and it all goes to stderr as it should even if a script wants it to go to stdout. On the happy path, only the master process will actually log anything to stderr so we turn that off after we "fork". On the unhappy path, logging to stderr/stdout *may* fail because the launcher process *may* have exited. We *could* have the master process as an intermediary but that's just excess code to avoid errors which *should* not happen. Regardless, any errror should still hit syslog.
Diffstat (limited to 'src/dhcpcd.c')
-rw-r--r--src/dhcpcd.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/src/dhcpcd.c b/src/dhcpcd.c
index c8589fe3..d5d67f64 100644
--- a/src/dhcpcd.c
+++ b/src/dhcpcd.c
@@ -361,7 +361,7 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
/* Don't use loginfo because this makes no sense in a log. */
if (!(logopts & LOGERR_QUIET))
- (void)dprintf(loggeterrfd(),
+ (void)fprintf(stderr,
"forked to background, child pid %d\n", getpid());
i = EXIT_SUCCESS;
if (write(ctx->fork_fd, &i, sizeof(i)) == -1)
@@ -371,11 +371,18 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx)
close(ctx->fork_fd);
ctx->fork_fd = -1;
- if (isatty(loggeterrfd())) {
- logopts &= ~LOGERR_ERR;
- logsetopts(logopts);
- logseterrfd(-1);
- }
+ /*
+ * Stop writing to stderr.
+ * On the happy path, only the master 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 master process and either disacrd it or pass
+ * it to the launcher process and then to stderr.
+ */
+ logopts &= ~LOGERR_ERR;
+ logsetopts(logopts);
#endif
}
@@ -2253,8 +2260,6 @@ printpidfile:
case 0:
ctx.fork_fd = fork_fd[1];
close(fork_fd[0]);
- logseterrfd(stderr_fd[1]);
- close(stderr_fd[0]);
#ifdef PRIVSEP_RIGHTS
if (ps_rights_limit_fd(fork_fd[1]) == -1 ||
ps_rights_limit_fd(stderr_fd[1]) == 1)
@@ -2263,9 +2268,15 @@ printpidfile:
goto exit_failure;
}
#endif
- if (freopen(_PATH_DEVNULL, "w", stdout) == NULL ||
- freopen(_PATH_DEVNULL, "w", stderr) == NULL)
- logerr("freopen");
+ /* Redirect stderr to the stderr socketpair.
+ * Redirect stdout as well.
+ * dhcpcd doesn't output via stdout, but something in
+ * a called script might. */
+ if (dup2(stderr_fd[1], STDERR_FILENO) == -1 ||
+ dup2(stderr_fd[1], STDOUT_FILENO) == -1)
+ logerr("dup2");
+ close(stderr_fd[0]);
+ close(stderr_fd[1]);
if (setsid() == -1) {
logerr("%s: setsid", __func__);
goto exit_failure;