mirror of
https://github.com/systemd/systemd.git
synced 2025-01-03 05:18:09 +03:00
terminal-util: temporarily turn on nonblocking mode when waiting for ANSI seq responses
We never know, maybe there's some spurious POLLIN and read() will fail with EAGAIN even though we saw POLLIN. Handle that. (this can happen if we area not the only process reading from the tty, or in case of hups and such). Fixes: #35499
This commit is contained in:
parent
9914b95a3f
commit
a0c314d6b0
@ -1900,6 +1900,7 @@ static int scan_background_color_response(
|
|||||||
}
|
}
|
||||||
|
|
||||||
int get_default_background_color(double *ret_red, double *ret_green, double *ret_blue) {
|
int get_default_background_color(double *ret_red, double *ret_green, double *ret_blue) {
|
||||||
|
_cleanup_close_ int nonblock_input_fd = -EBADF;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(ret_red);
|
assert(ret_red);
|
||||||
@ -1933,6 +1934,13 @@ int get_default_background_color(double *ret_red, double *ret_green, double *ret
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
|
/* Open a 2nd input fd, in non-blocking mode, so that we won't ever hang in read() should someone
|
||||||
|
* else process the POLLIN. */
|
||||||
|
|
||||||
|
nonblock_input_fd = fd_reopen(STDIN_FILENO, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
|
||||||
|
if (nonblock_input_fd < 0)
|
||||||
|
return nonblock_input_fd;
|
||||||
|
|
||||||
usec_t end = usec_add(now(CLOCK_MONOTONIC), 333 * USEC_PER_MSEC);
|
usec_t end = usec_add(now(CLOCK_MONOTONIC), 333 * USEC_PER_MSEC);
|
||||||
char buf[STRLEN(ANSI_OSC "11;rgb:0/0/0" ANSI_ST)]; /* shortest possible reply */
|
char buf[STRLEN(ANSI_OSC "11;rgb:0/0/0" ANSI_ST)]; /* shortest possible reply */
|
||||||
size_t buf_full = 0;
|
size_t buf_full = 0;
|
||||||
@ -1941,13 +1949,12 @@ int get_default_background_color(double *ret_red, double *ret_green, double *ret
|
|||||||
for (bool first = true;; first = false) {
|
for (bool first = true;; first = false) {
|
||||||
if (buf_full == 0) {
|
if (buf_full == 0) {
|
||||||
usec_t n = now(CLOCK_MONOTONIC);
|
usec_t n = now(CLOCK_MONOTONIC);
|
||||||
|
|
||||||
if (n >= end) {
|
if (n >= end) {
|
||||||
r = -EOPNOTSUPP;
|
r = -EOPNOTSUPP;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = fd_wait_for_event(STDIN_FILENO, POLLIN, usec_sub_unsigned(end, n));
|
r = fd_wait_for_event(nonblock_input_fd, POLLIN, usec_sub_unsigned(end, n));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
@ -1958,8 +1965,10 @@ int get_default_background_color(double *ret_red, double *ret_green, double *ret
|
|||||||
/* On the first try, read multiple characters, i.e. the shortest valid
|
/* On the first try, read multiple characters, i.e. the shortest valid
|
||||||
* reply. Afterwards read byte-wise, since we don't want to read too much, and
|
* reply. Afterwards read byte-wise, since we don't want to read too much, and
|
||||||
* unnecessarily drop too many characters from the input queue. */
|
* unnecessarily drop too many characters from the input queue. */
|
||||||
ssize_t l = read(STDIN_FILENO, buf, first ? sizeof(buf) : 1);
|
ssize_t l = read(nonblock_input_fd, buf, first ? sizeof(buf) : 1);
|
||||||
if (l < 0) {
|
if (l < 0) {
|
||||||
|
if (errno == EAGAIN)
|
||||||
|
continue;
|
||||||
r = -errno;
|
r = -errno;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
@ -2083,6 +2092,8 @@ int terminal_get_size_by_dsr(
|
|||||||
unsigned *ret_rows,
|
unsigned *ret_rows,
|
||||||
unsigned *ret_columns) {
|
unsigned *ret_columns) {
|
||||||
|
|
||||||
|
_cleanup_close_ int nonblock_input_fd = -EBADF;
|
||||||
|
|
||||||
assert(input_fd >= 0);
|
assert(input_fd >= 0);
|
||||||
assert(output_fd >= 0);
|
assert(output_fd >= 0);
|
||||||
|
|
||||||
@ -2130,6 +2141,13 @@ int terminal_get_size_by_dsr(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
|
/* Open a 2nd input fd, in non-blocking mode, so that we won't ever hang in read() should someone
|
||||||
|
* else process the POLLIN. */
|
||||||
|
|
||||||
|
nonblock_input_fd = fd_reopen(input_fd, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
|
||||||
|
if (nonblock_input_fd < 0)
|
||||||
|
return nonblock_input_fd;
|
||||||
|
|
||||||
usec_t end = usec_add(now(CLOCK_MONOTONIC), 333 * USEC_PER_MSEC);
|
usec_t end = usec_add(now(CLOCK_MONOTONIC), 333 * USEC_PER_MSEC);
|
||||||
char buf[STRLEN("\x1B[1;1R")]; /* The shortest valid reply possible */
|
char buf[STRLEN("\x1B[1;1R")]; /* The shortest valid reply possible */
|
||||||
size_t buf_full = 0;
|
size_t buf_full = 0;
|
||||||
@ -2138,13 +2156,12 @@ int terminal_get_size_by_dsr(
|
|||||||
for (bool first = true;; first = false) {
|
for (bool first = true;; first = false) {
|
||||||
if (buf_full == 0) {
|
if (buf_full == 0) {
|
||||||
usec_t n = now(CLOCK_MONOTONIC);
|
usec_t n = now(CLOCK_MONOTONIC);
|
||||||
|
|
||||||
if (n >= end) {
|
if (n >= end) {
|
||||||
r = -EOPNOTSUPP;
|
r = -EOPNOTSUPP;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = fd_wait_for_event(input_fd, POLLIN, usec_sub_unsigned(end, n));
|
r = fd_wait_for_event(nonblock_input_fd, POLLIN, usec_sub_unsigned(end, n));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
@ -2155,8 +2172,11 @@ int terminal_get_size_by_dsr(
|
|||||||
/* On the first try, read multiple characters, i.e. the shortest valid
|
/* On the first try, read multiple characters, i.e. the shortest valid
|
||||||
* reply. Afterwards read byte-wise, since we don't want to read too much, and
|
* reply. Afterwards read byte-wise, since we don't want to read too much, and
|
||||||
* unnecessarily drop too many characters from the input queue. */
|
* unnecessarily drop too many characters from the input queue. */
|
||||||
ssize_t l = read(input_fd, buf, first ? sizeof(buf) : 1);
|
ssize_t l = read(nonblock_input_fd, buf, first ? sizeof(buf) : 1);
|
||||||
if (l < 0) {
|
if (l < 0) {
|
||||||
|
if (errno == EAGAIN)
|
||||||
|
continue;
|
||||||
|
|
||||||
r = -errno;
|
r = -errno;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user