Switch from PTY to pipe for service log redirection

The PTY approach caused isatty() to return true for services using
the log directive, triggering programs like fprintd (using glib) to
emit ANSI escape codes and other TTY-specific formatting in syslog.

Using a standard pipe ensures isatty() correctly returns false, so
programs produce plain text output suitable for logging.

For services that require line-buffered output, users can wrap the
command with `stdbuf -oL` as documented in doc/config/logging.md.

Fixes #455

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2025-12-07 09:38:13 +01:00
1 parent 178301baf2
commit d9a0c2dce9
2 files changed
+37 -22

No files matched your search

+15 -22
View File
@@ -274,25 +274,22 @@ static int lredirect(svc_t *svc)
{
static int have_sysklogd = -1;
pid_t svc_pid = getpid();
int pipefd[2];
pid_t pid;
int fd;
/*
* Open PTY to connect to logger. A pty isn't buffered
* like a pipe, and it eats newlines so they aren't logged
* Use a pipe to connect to logger. This ensures isatty()
* returns false for the service, preventing programs from
* emitting ANSI escape codes and other TTY-specific output.
*/
fd = posix_openpt(O_RDWR);
if (fd == -1) {
dbg("Failed posix_openpt(), errno %d: %s", errno, strerror(errno));
svc->log.enabled = 0;
return -1;
}
if (grantpt(fd) == -1 || unlockpt(fd) == -1) {
dbg("Failed grantpt()|unlockpt(), errno %d: %s", errno, strerror(errno));
close(fd);
if (pipe(pipefd) == -1) {
dbg("Failed pipe(), errno %d: %s", errno, strerror(errno));
svc->log.enabled = 0;
return -1;
}
fd = pipefd[1]; /* Write end for service */
/*
* First time, check if we have sysklogd logger tool.
@@ -322,17 +319,12 @@ static int lredirect(svc_t *svc)
char *prio = "daemon.info";
char buf[MAX_IDENT_LEN];
char *tag;
int fds;
sched_yield();
fds = open(ptsname(fd), O_RDONLY);
close(fd);
if (fds == -1) {
logit(LOG_WARNING, "failed open() ptsname(%d), errno %d", fd, errno);
_exit(0);
}
dup2(fds, STDIN_FILENO);
close(pipefd[1]); /* Close write end in logger */
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[0]);
/* Reset signals */
sig_unblock();
@@ -388,10 +380,11 @@ static int lredirect(svc_t *svc)
_exit(1);
}
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
close(pipefd[0]); /* Close read end in service */
dup2(pipefd[1], STDOUT_FILENO);
dup2(pipefd[1], STDERR_FILENO);
return close(fd);
return close(pipefd[1]);
}
/*