close(ctx->fork_fd);
ctx->fork_fd = -1;
- if (isatty(STDERR_FILENO)) {
+ if (isatty(loggeterrfd())) {
logopts &= ~LOGERR_ERR;
logsetopts(logopts);
+ logseterrfd(-1);
}
#endif
}
loginfox(PACKAGE "-" VERSION " starting");
if (freopen(_PATH_DEVNULL, "r", stdin) == NULL)
- logerr("%s: freopen", __func__);
+ logerr("%s: freopen stdin", __func__);
+
#ifdef PRIVSEP
ps_init(&ctx);
}
#endif
+ if (isatty(STDOUT_FILENO) &&
+ freopen(_PATH_DEVNULL, "r", stdout) == NULL)
+ logerr("%s: freopen stdout", __func__);
+ if (isatty(STDERR_FILENO)) {
+ int fd = dup(STDERR_FILENO);
+
+ if (fd == -1)
+ logerr("%s: dup", __func__);
+ else if (logseterrfd(fd) == -1)
+ logerr("%s: logseterrfd", __func__);
+ else if (freopen(_PATH_DEVNULL, "r", stderr) == NULL) {
+ logseterrfd(-1);
+ logerr("%s: freopen stderr", __func__);
+ }
+ }
+
#if defined(BSD) && defined(INET6)
/* Disable the kernel RTADV sysctl as early as possible. */
if (ctx.options & DHCPCD_IPV6 && ctx.options & DHCPCD_IPV6RS)
struct logctx {
char log_buf[BUFSIZ];
unsigned int log_opts;
+ FILE *log_err;
#ifndef SMALL
FILE *log_file;
#ifdef LOGERR_TAG
__printflike(3, 0) static int
vlogprintf_r(struct logctx *ctx, FILE *stream, const char *fmt, va_list args)
{
+ FILE *err;
int len = 0, e;
va_list a;
#ifndef SMALL
bool log_tag;
#endif
- if ((stream == stderr && ctx->log_opts & LOGERR_ERR_DATE) ||
- (stream != stderr && ctx->log_opts & LOGERR_LOG_DATE))
+ err = ctx->log_err == NULL ? stderr : ctx->log_err;
+ if ((stream == err && ctx->log_opts & LOGERR_ERR_DATE) ||
+ (stream != err && ctx->log_opts & LOGERR_LOG_DATE))
{
if ((e = logprintdate(stream)) == -1)
return -1;
}
#ifdef LOGERR_TAG
- log_tag = ((stream == stderr && ctx->log_opts & LOGERR_ERR_TAG) ||
- (stream != stderr && ctx->log_opts & LOGERR_LOG_TAG));
+ log_tag = ((stream == err && ctx->log_opts & LOGERR_ERR_TAG) ||
+ (stream != err && ctx->log_opts & LOGERR_LOG_TAG));
if (log_tag) {
if (ctx->log_tag == NULL)
ctx->log_tag = getprogname();
}
#endif
- log_pid = ((stream == stderr && ctx->log_opts & LOGERR_ERR_PID) ||
- (stream != stderr && ctx->log_opts & LOGERR_LOG_PID));
+ log_pid = ((stream == err && ctx->log_opts & LOGERR_ERR_PID) ||
+ (stream != err && ctx->log_opts & LOGERR_LOG_PID));
if (log_pid) {
if ((e = fprintf(stream, "[%d]", getpid())) == -1)
return -1;
(pri <= LOG_ERR ||
(!(ctx->log_opts & LOGERR_QUIET) && pri <= LOG_INFO) ||
(ctx->log_opts & LOGERR_DEBUG && pri <= LOG_DEBUG)))
- len = vlogprintf_r(ctx, stderr, fmt, args);
+ {
+ FILE *err;
+
+ err = ctx->log_err == NULL ? stderr : ctx->log_err;
+ len = vlogprintf_r(ctx, err, fmt, args);
+ }
if (!(ctx->log_opts & LOGERR_LOG))
return len;
}
#endif
+int
+loggeterrfd(void)
+{
+ struct logctx *ctx = &_logctx;
+ FILE *err = ctx->log_err == NULL ? stderr : ctx->log_err;
+
+ return fileno(err);
+}
+
+int
+logseterrfd(int fd)
+{
+ struct logctx *ctx = &_logctx;
+
+ if (ctx->log_err != NULL)
+ fclose(ctx->log_err);
+ if (fd == -1) {
+ ctx->log_err = NULL;
+ return 0;
+ }
+ ctx->log_err = fdopen(fd, "a");
+ return ctx->log_err == NULL ? -1 : 0;
+}
+
int
logopen(const char *path)
{