mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
Merge pull request #30183 from poettering/nlcr
NL → CRNL conversion fixes when logging at the same time as ptyfwd runs
This commit is contained in:
@@ -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) {
|
||||
|
||||
|
||||
@@ -187,14 +187,12 @@ int inode_same_at(int fda, const char *filea, int fdb, const char *fileb, int fl
|
||||
struct stat a, b;
|
||||
|
||||
assert(fda >= 0 || fda == AT_FDCWD);
|
||||
assert(filea);
|
||||
assert(fdb >= 0 || fdb == AT_FDCWD);
|
||||
assert(fileb);
|
||||
|
||||
if (fstatat(fda, filea, &a, flags) < 0)
|
||||
if (fstatat(fda, strempty(filea), &a, flags) < 0)
|
||||
return log_debug_errno(errno, "Cannot stat %s: %m", filea);
|
||||
|
||||
if (fstatat(fdb, fileb, &b, flags) < 0)
|
||||
if (fstatat(fdb, strempty(fileb), &b, flags) < 0)
|
||||
return log_debug_errno(errno, "Cannot stat %s: %m", fileb);
|
||||
|
||||
return stat_inode_same(&a, &b);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "ptyfwd.h"
|
||||
#include "stat-util.h"
|
||||
#include "terminal-util.h"
|
||||
#include "time-util.h"
|
||||
|
||||
@@ -142,7 +143,7 @@ static bool look_for_escape(PTYForward *f, const char *buffer, size_t n) {
|
||||
if (*p == 0x1D) {
|
||||
usec_t nw = now(CLOCK_MONOTONIC);
|
||||
|
||||
if (f->escape_counter == 0 || nw > f->escape_timestamp + ESCAPE_USEC) {
|
||||
if (f->escape_counter == 0 || nw > f->escape_timestamp + ESCAPE_USEC) {
|
||||
f->escape_timestamp = nw;
|
||||
f->escape_counter = 1;
|
||||
} else {
|
||||
@@ -228,7 +229,7 @@ static int shovel(PTYForward *f) {
|
||||
f->stdin_hangup = true;
|
||||
|
||||
f->stdin_event_source = sd_event_source_unref(f->stdin_event_source);
|
||||
} else {
|
||||
} else {
|
||||
/* Check if ^] has been pressed three times within one second. If we get this we quite
|
||||
* immediately. */
|
||||
if (look_for_escape(f, f->in_buffer + f->in_buffer_full, k))
|
||||
@@ -266,12 +267,9 @@ static int shovel(PTYForward *f) {
|
||||
k = read(f->master, f->out_buffer + f->out_buffer_full, LINE_MAX - f->out_buffer_full);
|
||||
if (k < 0) {
|
||||
|
||||
/* Note that EIO on the master device
|
||||
* might be caused by vhangup() or
|
||||
* temporary closing of everything on
|
||||
* the other side, we treat it like
|
||||
* EAGAIN here and try again, unless
|
||||
* ignore_vhangup is off. */
|
||||
/* Note that EIO on the master device might be caused by vhangup() or
|
||||
* temporary closing of everything on the other side, we treat it like EAGAIN
|
||||
* here and try again, unless ignore_vhangup is off. */
|
||||
|
||||
if (errno == EAGAIN || (errno == EIO && ignore_vhangup(f)))
|
||||
f->master_readable = false;
|
||||
@@ -284,7 +282,7 @@ static int shovel(PTYForward *f) {
|
||||
log_error_errno(errno, "read(): %m");
|
||||
return pty_forward_done(f, -errno);
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
f->read_from_master = true;
|
||||
f->out_buffer_full += (size_t) k;
|
||||
}
|
||||
@@ -480,8 +478,14 @@ int pty_forward_new(
|
||||
(void) ioctl(master, TIOCSWINSZ, &ws);
|
||||
|
||||
if (!(flags & PTY_FORWARD_READ_ONLY)) {
|
||||
int same;
|
||||
|
||||
assert(f->input_fd >= 0);
|
||||
|
||||
same = inode_same_at(f->input_fd, NULL, f->output_fd, NULL, AT_EMPTY_PATH);
|
||||
if (same < 0)
|
||||
return same;
|
||||
|
||||
if (tcgetattr(f->input_fd, &f->saved_stdin_attr) >= 0) {
|
||||
struct termios raw_stdin_attr;
|
||||
|
||||
@@ -489,11 +493,14 @@ int pty_forward_new(
|
||||
|
||||
raw_stdin_attr = f->saved_stdin_attr;
|
||||
cfmakeraw(&raw_stdin_attr);
|
||||
raw_stdin_attr.c_oflag = f->saved_stdin_attr.c_oflag;
|
||||
tcsetattr(f->input_fd, TCSANOW, &raw_stdin_attr);
|
||||
|
||||
if (!same)
|
||||
raw_stdin_attr.c_oflag = f->saved_stdin_attr.c_oflag;
|
||||
|
||||
(void) tcsetattr(f->input_fd, TCSANOW, &raw_stdin_attr);
|
||||
}
|
||||
|
||||
if (tcgetattr(f->output_fd, &f->saved_stdout_attr) >= 0) {
|
||||
if (!same && tcgetattr(f->output_fd, &f->saved_stdout_attr) >= 0) {
|
||||
struct termios raw_stdout_attr;
|
||||
|
||||
f->saved_stdout = true;
|
||||
@@ -502,7 +509,7 @@ int pty_forward_new(
|
||||
cfmakeraw(&raw_stdout_attr);
|
||||
raw_stdout_attr.c_iflag = f->saved_stdout_attr.c_iflag;
|
||||
raw_stdout_attr.c_lflag = f->saved_stdout_attr.c_lflag;
|
||||
tcsetattr(f->output_fd, TCSANOW, &raw_stdout_attr);
|
||||
(void) tcsetattr(f->output_fd, TCSANOW, &raw_stdout_attr);
|
||||
}
|
||||
|
||||
r = sd_event_add_io(f->event, &f->stdin_event_source, f->input_fd, EPOLLIN|EPOLLET, on_stdin_event, f);
|
||||
|
||||
Reference in New Issue
Block a user