diff --git a/src/basic/log.c b/src/basic/log.c index 0d78ecfd24..1470611a75 100644 --- a/src/basic/log.c +++ b/src/basic/log.c @@ -53,6 +53,7 @@ static int log_facility = LOG_DAEMON; static bool ratelimit_kmsg = true; static int console_fd = STDERR_FILENO; +static int console_fd_is_tty = -1; /* tri-state: -1 means don't know */ static int syslog_fd = -EBADF; static int kmsg_fd = -EBADF; static int journal_fd = -EBADF; @@ -108,12 +109,14 @@ bool _log_message_dummy = false; /* Always false */ static void log_close_console(void) { /* See comment in log_close_journal() */ (void) safe_close_above_stdio(TAKE_FD(console_fd)); + console_fd_is_tty = -1; } static int log_open_console(void) { if (!always_reopen_console) { console_fd = STDERR_FILENO; + console_fd_is_tty = -1; return 0; } @@ -125,6 +128,7 @@ static int log_open_console(void) { return fd; console_fd = fd_move_above_stdio(fd); + console_fd_is_tty = true; } return 0; @@ -381,6 +385,7 @@ void log_forget_fds(void) { /* Do not call from library code. */ console_fd = kmsg_fd = syslog_fd = journal_fd = -EBADF; + console_fd_is_tty = -1; } void log_set_max_level(int level) { @@ -404,6 +409,16 @@ void log_set_facility(int facility) { log_facility = facility; } +static bool check_console_fd_is_tty(void) { + if (console_fd < 0) + return false; + + if (console_fd_is_tty < 0) + console_fd_is_tty = isatty(console_fd) > 0; + + return console_fd_is_tty; +} + static int write_to_console( int level, int error, @@ -462,7 +477,12 @@ static int write_to_console( iovec[n++] = IOVEC_MAKE_STRING(buffer); if (off) iovec[n++] = IOVEC_MAKE_STRING(off); - iovec[n++] = IOVEC_MAKE_STRING("\n"); + + /* When writing to a TTY we output an extra '\r' (i.e. CR) first, to generate CRNL rather than just + * NL. This is a robustness thing in case the TTY is currently in raw mode (specifically: has the + * ONLCR flag off). We want that subsequent output definitely starts at the beginning of the line + * again, after all. If the TTY is not in raw mode the extra CR should not hurt. */ + iovec[n++] = IOVEC_MAKE_STRING(check_console_fd_is_tty() ? "\r\n" : "\n"); if (writev(console_fd, iovec, n) < 0) {