1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
5 #include <linux/magic.h>
6 #include <linux/tiocl.h>
11 #include <sys/inotify.h>
12 #include <sys/ioctl.h>
13 #include <sys/sysmacros.h>
18 #include "alloc-util.h"
19 #include "ansi-color.h"
21 #include "devnum-util.h"
22 #include "errno-util.h"
23 #include "extract-word.h"
27 #include "hexdecoct.h"
28 #include "inotify-util.h"
31 #include "namespace-util.h"
32 #include "parse-util.h"
33 #include "path-util.h"
34 #include "proc-cmdline.h"
35 #include "process-util.h"
36 #include "signal-util.h"
37 #include "socket-util.h"
38 #include "stat-util.h"
39 #include "stdio-util.h"
40 #include "string-util.h"
42 #include "terminal-util.h"
43 #include "time-util.h"
46 /* How much to wait for a reply to a terminal sequence */
47 #define CONSOLE_REPLY_WAIT_USEC (333 * USEC_PER_MSEC)
49 static volatile unsigned cached_columns
= 0;
50 static volatile unsigned cached_lines
= 0;
52 static volatile int cached_on_tty
= -1;
53 static volatile int cached_on_dev_null
= -1;
55 bool isatty_safe(int fd
) {
61 /* Linux/glibc returns EIO for hung up TTY on isatty(). Which is wrong, the thing doesn't stop being
62 * a TTY after all, just because it is temporarily hung up. Let's work around this here, until this
63 * is fixed in glibc. See: https://sourceware.org/bugzilla/show_bug.cgi?id=32103 */
67 /* Be resilient if we're working on stdio, since they're set up by parent process. */
68 assert(errno
!= EBADF
|| IN_SET(fd
, STDIN_FILENO
, STDOUT_FILENO
, STDERR_FILENO
));
74 _cleanup_close_
int fd
= -EBADF
;
76 /* Switch to the specified vt number. If the VT is specified <= 0 switch to the VT the kernel log messages go,
77 * if that's configured. */
79 fd
= open_terminal("/dev/tty0", O_RDWR
|O_NOCTTY
|O_CLOEXEC
|O_NONBLOCK
);
85 TIOCL_GETKMSGREDIRECT
,
89 if (ioctl(fd
, TIOCLINUX
, tiocl
) < 0)
92 vt
= tiocl
[0] <= 0 ? 1 : tiocl
[0];
95 return RET_NERRNO(ioctl(fd
, VT_ACTIVATE
, vt
));
98 int read_one_char(FILE *f
, char *ret
, usec_t t
, bool echo
, bool *need_nl
) {
99 _cleanup_free_
char *line
= NULL
;
100 struct termios old_termios
;
108 /* If this is a terminal, then switch canonical mode off, so that we can read a single
109 * character. (Note that fmemopen() streams do not have an fd associated with them, let's handle that
110 * nicely.) If 'echo' is false we'll also disable ECHO mode so that the pressed key is not made
111 * visible to the user. */
113 if (fd
>= 0 && tcgetattr(fd
, &old_termios
) >= 0) {
114 struct termios new_termios
= old_termios
;
116 new_termios
.c_lflag
&= ~(ICANON
|(echo
? 0 : ECHO
));
117 new_termios
.c_cc
[VMIN
] = 1;
118 new_termios
.c_cc
[VTIME
] = 0;
120 if (tcsetattr(fd
, TCSANOW
, &new_termios
) >= 0) {
123 if (t
!= USEC_INFINITY
) {
124 if (fd_wait_for_event(fd
, POLLIN
, t
) <= 0) {
125 (void) tcsetattr(fd
, TCSANOW
, &old_termios
);
130 r
= safe_fgetc(f
, &c
);
131 (void) tcsetattr(fd
, TCSANOW
, &old_termios
);
138 *need_nl
= c
!= '\n';
145 if (t
!= USEC_INFINITY
&& fd
>= 0) {
146 /* Let's wait the specified amount of time for input. When we have no fd we skip this, under
147 * the assumption that this is an fmemopen() stream or so where waiting doesn't make sense
148 * anyway, as the data is either already in the stream or cannot possible be placed there
149 * while we access the stream */
151 if (fd_wait_for_event(fd
, POLLIN
, t
) <= 0)
155 /* If this is not a terminal, then read a full line instead */
157 r
= read_line(f
, 16, &line
); /* longer than necessary, to eat up UTF-8 chars/vt100 key sequences */
163 if (strlen(line
) != 1)
173 #define DEFAULT_ASK_REFRESH_USEC (2*USEC_PER_SEC)
175 int ask_char(char *ret
, const char *replies
, const char *fmt
, ...) {
187 fputs(ansi_highlight(), stdout
);
195 fputs(ansi_normal(), stdout
);
199 r
= read_one_char(stdin
, &c
, DEFAULT_ASK_REFRESH_USEC
, /* echo= */ true, &need_nl
);
206 puts("Bad input, please try again.");
217 if (strchr(replies
, c
)) {
222 puts("Read unexpected character, please try again.");
226 typedef enum CompletionResult
{
227 COMPLETION_ALREADY
, /* the input string is already complete */
228 COMPLETION_FULL
, /* completed the input string to be complete now */
229 COMPLETION_PARTIAL
, /* completed the input string so that is still incomplete */
230 COMPLETION_NONE
, /* found no matching completion */
231 _COMPLETION_RESULT_MAX
,
232 _COMPLETION_RESULT_INVALID
= -EINVAL
,
233 _COMPLETION_RESULT_ERRNO_MAX
= -ERRNO_MAX
,
236 static CompletionResult
pick_completion(const char *string
, char *const*completions
, char **ret
) {
237 _cleanup_free_
char *found
= NULL
;
238 bool partial
= false;
240 string
= strempty(string
);
242 STRV_FOREACH(c
, completions
) {
244 /* Ignore entries that are not actually completions */
245 if (!startswith(*c
, string
))
248 /* Store first completion that matches */
257 /* If there's another completion that works truncate the one we already found by common
259 size_t n
= str_common_prefix(found
, *c
);
267 *ret
= TAKE_PTR(found
);
270 return COMPLETION_NONE
;
272 return COMPLETION_PARTIAL
;
274 return streq(string
, *ret
) ? COMPLETION_ALREADY
: COMPLETION_FULL
;
277 static void clear_by_backspace(size_t n
) {
278 /* Erase the specified number of character cells backwards on the terminal */
279 for (size_t i
= 0; i
< n
; i
++)
280 fputs("\b \b", stdout
);
285 GetCompletionsCallback get_completions
,
287 const char *text
, ...) {
295 /* Output the prompt */
296 fputs(ansi_highlight(), stdout
);
300 fputs(ansi_normal(), stdout
);
303 _cleanup_free_
char *string
= NULL
;
306 /* Do interactive logic only if stdin + stdout are connected to the same place. And yes, we could use
307 * STDIN_FILENO and STDOUT_FILENO here, but let's be overly correct for once, after all libc allows
308 * swapping out stdin/stdout. */
309 int fd_input
= fileno(stdin
);
310 int fd_output
= fileno(stdout
);
311 if (fd_input
< 0 || fd_output
< 0 || same_fd(fd_input
, fd_output
) <= 0)
314 /* Try to disable echo, which also tells us if this even is a terminal */
315 struct termios old_termios
;
316 if (tcgetattr(fd_input
, &old_termios
) < 0)
319 struct termios new_termios
= old_termios
;
320 termios_disable_echo(&new_termios
);
321 if (tcsetattr(fd_input
, TCSANOW
, &new_termios
) < 0)
325 int c
= fgetc(stdin
);
327 /* On EOF or NUL, end the request, don't output anything anymore */
328 if (IN_SET(c
, EOF
, 0))
331 /* On Return also end the request, but make this visible */
332 if (IN_SET(c
, '\n', '\r')) {
340 _cleanup_strv_free_
char **completions
= NULL
;
341 if (get_completions
) {
342 r
= get_completions(string
, &completions
, userdata
);
347 _cleanup_free_
char *new_string
= NULL
;
348 CompletionResult cr
= pick_completion(string
, completions
, &new_string
);
353 if (IN_SET(cr
, COMPLETION_PARTIAL
, COMPLETION_FULL
)) {
354 /* Output the new suffix we learned */
355 fputs(ASSERT_PTR(startswith(new_string
, strempty(string
))), stdout
);
357 /* And update the whole string */
358 free_and_replace(string
, new_string
);
361 if (cr
== COMPLETION_NONE
)
362 fputc('\a', stdout
); /* BEL */
364 if (IN_SET(cr
, COMPLETION_PARTIAL
, COMPLETION_ALREADY
)) {
365 /* If this worked only partially, or if the user hit TAB even though we were
366 * complete already, then show the remaining options (in the latter case just
370 _cleanup_strv_free_
char **filtered
= strv_filter_prefix(completions
, string
);
376 r
= show_menu(filtered
,
377 /* n_columns= */ SIZE_MAX
,
378 /* column_width= */ SIZE_MAX
,
379 /* ellipsize_percentage= */ 0,
380 /* grey_prefix=*/ string
,
381 /* with_numbers= */ false);
385 /* Show the prompt again */
386 fputs(ansi_highlight(), stdout
);
390 fputs(ansi_normal(), stdout
);
391 fputs(string
, stdout
);
394 } else if (IN_SET(c
, '\b', 127)) {
398 fputc('\a', stdout
); /* BEL */
400 size_t m
= utf8_last_length(string
, n
);
402 char *e
= string
+ n
- m
;
403 clear_by_backspace(utf8_console_width(e
));
409 } else if (c
== 21) {
410 /* Ctrl-u → erase all input */
412 clear_by_backspace(utf8_console_width(string
));
419 /* Ctrl-d → cancel this field input */
424 } else if (char_is_cc(c
) || n
>= LINE_MAX
)
425 /* refuse control characters and too long strings */
426 fputc('\a', stdout
); /* BEL */
430 if (!GREEDY_REALLOC(string
, n
+2)) {
435 string
[n
++] = (char) c
;
444 if (tcsetattr(fd_input
, TCSANOW
, &old_termios
) < 0)
453 *ret
= TAKE_PTR(string
);
457 (void) tcsetattr(fd_input
, TCSANOW
, &old_termios
);
461 /* A simple fallback without TTY magic */
462 r
= read_line(stdin
, LONG_LINE_MAX
, &string
);
468 *ret
= TAKE_PTR(string
);
472 bool any_key_to_proceed(void) {
474 /* Insert a new line here as well as to when the user inputs, as this is also used during the boot up
475 * sequence when status messages may be interleaved with the current program output. This ensures
476 * that the status messages aren't appended on the same line as this message. */
479 fputs(ansi_highlight_magenta(), stdout
);
480 fputs("-- Press any key to proceed --", stdout
);
481 fputs(ansi_normal(), stdout
);
486 (void) read_one_char(stdin
, &key
, USEC_INFINITY
, /* echo= */ false, /* need_nl= */ NULL
);
494 static size_t widest_list_element(char *const*l
) {
497 /* Returns the largest console width of all elements in 'l' */
500 w
= MAX(w
, utf8_console_width(*i
));
505 int show_menu(char **x
,
508 unsigned ellipsize_percentage
,
509 const char *grey_prefix
,
512 assert(n_columns
> 0);
514 if (n_columns
== SIZE_MAX
)
517 if (column_width
== SIZE_MAX
) {
518 size_t widest
= widest_list_element(x
);
520 /* If not specified, derive column width from screen width */
521 size_t column_max
= (columns()-1) / n_columns
;
523 /* Subtract room for numbers */
524 if (with_numbers
&& column_max
> 6)
527 /* If columns would get too tight let's make this a linear list instead. */
528 if (column_max
< 10 && widest
> 10) {
530 column_max
= columns()-1;
532 if (with_numbers
&& column_max
> 6)
536 column_width
= CLAMP(widest
+1, 10U, column_max
);
539 size_t n
= strv_length(x
);
540 size_t per_column
= DIV_ROUND_UP(n
, n_columns
);
542 size_t break_lines
= lines();
546 /* The first page gets two extra lines, since we want to show
548 size_t break_modulo
= break_lines
;
549 if (break_modulo
> 3)
552 for (size_t i
= 0; i
< per_column
; i
++) {
554 for (size_t j
= 0; j
< n_columns
; j
++) {
555 _cleanup_free_
char *e
= NULL
;
557 if (j
* per_column
+ i
>= n
)
560 e
= ellipsize(x
[j
* per_column
+ i
], column_width
, ellipsize_percentage
);
567 j
* per_column
+ i
+ 1,
570 if (grey_prefix
&& startswith(e
, grey_prefix
)) {
571 size_t k
= MIN(strlen(grey_prefix
), column_width
);
577 (int) (column_width
- k
), e
+k
);
579 printf("%-*s", (int) column_width
, e
);
584 /* on the first screen we reserve 2 extra lines for the title */
585 if (i
% break_lines
== break_modulo
)
586 if (!any_key_to_proceed())
593 int open_terminal(const char *name
, int mode
) {
594 _cleanup_close_
int fd
= -EBADF
;
597 * If a TTY is in the process of being closed opening it might cause EIO. This is horribly awful, but
598 * unlikely to be changed in the kernel. Hence we work around this problem by retrying a couple of
601 * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
604 assert((mode
& (O_CREAT
|O_PATH
|O_DIRECTORY
|O_TMPFILE
)) == 0);
606 for (unsigned c
= 0;; c
++) {
607 fd
= open(name
, mode
, 0);
614 /* Max 1s in total */
618 (void) usleep_safe(50 * USEC_PER_MSEC
);
621 if (!isatty_safe(fd
))
627 int acquire_terminal(
629 AcquireTerminalFlags flags
,
632 _cleanup_close_
int notify
= -EBADF
, fd
= -EBADF
;
633 usec_t ts
= USEC_INFINITY
;
638 AcquireTerminalFlags mode
= flags
& _ACQUIRE_TERMINAL_MODE_MASK
;
639 assert(IN_SET(mode
, ACQUIRE_TERMINAL_TRY
, ACQUIRE_TERMINAL_FORCE
, ACQUIRE_TERMINAL_WAIT
));
640 assert(mode
== ACQUIRE_TERMINAL_WAIT
|| !FLAGS_SET(flags
, ACQUIRE_TERMINAL_WATCH_SIGTERM
));
642 /* We use inotify to be notified when the tty is closed. We create the watch before checking if we can actually
643 * acquire it, so that we don't lose any event.
645 * Note: strictly speaking this actually watches for the device being closed, it does *not* really watch
646 * whether a tty loses its controlling process. However, unless some rogue process uses TIOCNOTTY on /dev/tty
647 * *after* closing its tty otherwise this will not become a problem. As long as the administrator makes sure to
648 * not configure any service on the same tty as an untrusted user this should not be a problem. (Which they
649 * probably should not do anyway.) */
651 if (mode
== ACQUIRE_TERMINAL_WAIT
) {
652 notify
= inotify_init1(IN_CLOEXEC
| IN_NONBLOCK
);
656 wd
= inotify_add_watch(notify
, name
, IN_CLOSE
);
660 if (timeout
!= USEC_INFINITY
)
661 ts
= now(CLOCK_MONOTONIC
);
664 /* If we are called with ACQUIRE_TERMINAL_WATCH_SIGTERM we'll unblock SIGTERM during ppoll() temporarily */
666 assert_se(sigprocmask(SIG_SETMASK
, /* newset= */ NULL
, &poll_ss
) >= 0);
667 if (flags
& ACQUIRE_TERMINAL_WATCH_SIGTERM
) {
668 assert_se(sigismember(&poll_ss
, SIGTERM
) > 0);
669 assert_se(sigdelset(&poll_ss
, SIGTERM
) >= 0);
674 r
= flush_fd(notify
);
679 /* We pass here O_NOCTTY only so that we can check the return value TIOCSCTTY and have a reliable way
680 * to figure out if we successfully became the controlling process of the tty */
681 fd
= open_terminal(name
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
685 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed if we already own the tty. */
686 struct sigaction sa_old
;
687 assert_se(sigaction(SIGHUP
, &sigaction_ignore
, &sa_old
) >= 0);
689 /* First, try to get the tty */
690 r
= RET_NERRNO(ioctl(fd
, TIOCSCTTY
, mode
== ACQUIRE_TERMINAL_FORCE
));
692 /* Reset signal handler to old value */
693 assert_se(sigaction(SIGHUP
, &sa_old
, NULL
) >= 0);
695 /* Success? Exit the loop now! */
699 /* Any failure besides -EPERM? Fail, regardless of the mode. */
703 if (flags
& ACQUIRE_TERMINAL_PERMISSIVE
) /* If we are in permissive mode, then EPERM is fine, turn this
704 * into a success. Note that EPERM is also returned if we
705 * already are the owner of the TTY. */
708 if (mode
!= ACQUIRE_TERMINAL_WAIT
) /* If we are in TRY or FORCE mode, then propagate EPERM as EPERM */
716 if (timeout
== USEC_INFINITY
)
717 left
= USEC_INFINITY
;
719 assert(ts
!= USEC_INFINITY
);
721 usec_t n
= usec_sub_unsigned(now(CLOCK_MONOTONIC
), ts
);
741 union inotify_event_buffer buffer
;
743 l
= read(notify
, &buffer
, sizeof(buffer
));
745 if (ERRNO_IS_TRANSIENT(errno
))
751 FOREACH_INOTIFY_EVENT(e
, buffer
, l
) {
752 if (e
->mask
& IN_Q_OVERFLOW
) /* If we hit an inotify queue overflow, simply check if the terminal is up for grabs now. */
755 if (e
->wd
!= wd
|| !(e
->mask
& IN_CLOSE
)) /* Safety checks */
762 /* We close the tty fd here since if the old session ended our handle will be dead. It's important that
763 * we do this after sleeping, so that we don't enter an endless loop. */
770 int release_terminal(void) {
771 _cleanup_close_
int fd
= -EBADF
;
774 fd
= open("/dev/tty", O_RDWR
|O_NOCTTY
|O_CLOEXEC
|O_NONBLOCK
);
778 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
779 * by our own TIOCNOTTY */
780 struct sigaction sa_old
;
781 assert_se(sigaction(SIGHUP
, &sigaction_ignore
, &sa_old
) >= 0);
783 r
= RET_NERRNO(ioctl(fd
, TIOCNOTTY
));
785 assert_se(sigaction(SIGHUP
, &sa_old
, NULL
) >= 0);
790 int terminal_new_session(void) {
792 /* Make us the new session leader, and set stdin tty to be our controlling terminal.
794 * Why stdin? Well, the ctty logic is relevant for signal delivery mostly, i.e. if people hit C-c
795 * or the line is hung up. Such events are basically just a form of input, via a side channel
796 * (that side channel being signal delivery, i.e. SIGINT, SIGHUP et al). Hence we focus on input,
797 * not output here. */
799 if (!isatty_safe(STDIN_FILENO
))
803 return RET_NERRNO(ioctl(STDIN_FILENO
, TIOCSCTTY
, 0));
806 void terminal_detach_session(void) {
808 (void) release_terminal();
811 int terminal_vhangup_fd(int fd
) {
813 return RET_NERRNO(ioctl(fd
, TIOCVHANGUP
));
816 int terminal_vhangup(const char *tty
) {
817 _cleanup_close_
int fd
= -EBADF
;
821 fd
= open_terminal(tty
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
825 return terminal_vhangup_fd(fd
);
828 int vt_disallocate(const char *tty_path
) {
831 /* Deallocate the VT if possible. If not possible (i.e. because it is the active one), at least clear
832 * it entirely (including the scrollback buffer). */
834 int ttynr
= vtnr_from_tty(tty_path
);
836 _cleanup_close_
int fd
= open_terminal("/dev/tty0", O_RDWR
|O_NOCTTY
|O_CLOEXEC
|O_NONBLOCK
);
840 /* Try to deallocate */
841 if (ioctl(fd
, VT_DISALLOCATE
, ttynr
) >= 0)
847 /* So this is not a VT (in which case we cannot deallocate it), or we failed to deallocate. Let's at
848 * least clear the screen. */
850 _cleanup_close_
int fd2
= open_terminal(tty_path
, O_WRONLY
|O_NOCTTY
|O_CLOEXEC
|O_NONBLOCK
);
854 return loop_write_full(fd2
,
855 "\033[r" /* clear scrolling region */
856 "\033[H" /* move home */
857 "\033[3J" /* clear screen including scrollback, requires Linux 2.6.40 */
858 "\033c", /* reset to initial state */
860 100 * USEC_PER_MSEC
);
863 static int vt_default_utf8(void) {
864 _cleanup_free_
char *b
= NULL
;
867 /* Read the default VT UTF8 setting from the kernel */
869 r
= read_one_line_file("/sys/module/vt/parameters/default_utf8", &b
);
873 return parse_boolean(b
);
876 static int vt_reset_keyboard(int fd
) {
881 /* If we can't read the default, then default to Unicode. It's 2024 after all. */
882 r
= vt_default_utf8();
884 log_debug_errno(r
, "Failed to determine kernel VT UTF-8 mode, assuming enabled: %m");
886 kb
= vt_default_utf8() != 0 ? K_UNICODE
: K_XLATE
;
887 return RET_NERRNO(ioctl(fd
, KDSKBMODE
, kb
));
890 static int terminal_reset_ioctl(int fd
, bool switch_to_text
) {
891 struct termios termios
;
894 /* Set terminal to some sane defaults */
898 /* We leave locked terminal attributes untouched, so that Plymouth may set whatever it wants to set,
899 * and we don't interfere with that. */
901 /* Disable exclusive mode, just in case */
902 if (ioctl(fd
, TIOCNXCL
) < 0)
903 log_debug_errno(errno
, "TIOCNXCL ioctl failed on TTY, ignoring: %m");
905 /* Switch to text mode */
907 if (ioctl(fd
, KDSETMODE
, KD_TEXT
) < 0)
908 log_debug_errno(errno
, "KDSETMODE ioctl for switching to text mode failed on TTY, ignoring: %m");
910 /* Set default keyboard mode */
911 r
= vt_reset_keyboard(fd
);
913 log_debug_errno(r
, "Failed to reset VT keyboard, ignoring: %m");
915 if (tcgetattr(fd
, &termios
) < 0) {
916 r
= log_debug_errno(errno
, "Failed to get terminal parameters: %m");
920 /* We only reset the stuff that matters to the software. How
921 * hardware is set up we don't touch assuming that somebody
922 * else will do that for us */
924 termios
.c_iflag
&= ~(IGNBRK
| BRKINT
| ISTRIP
| INLCR
| IGNCR
| IUCLC
);
925 termios
.c_iflag
|= ICRNL
| IMAXBEL
| IUTF8
;
926 termios
.c_oflag
|= ONLCR
| OPOST
;
927 termios
.c_cflag
|= CREAD
;
928 termios
.c_lflag
= ISIG
| ICANON
| IEXTEN
| ECHO
| ECHOE
| ECHOK
| ECHOCTL
| ECHOKE
;
930 termios
.c_cc
[VINTR
] = 03; /* ^C */
931 termios
.c_cc
[VQUIT
] = 034; /* ^\ */
932 termios
.c_cc
[VERASE
] = 0177;
933 termios
.c_cc
[VKILL
] = 025; /* ^X */
934 termios
.c_cc
[VEOF
] = 04; /* ^D */
935 termios
.c_cc
[VSTART
] = 021; /* ^Q */
936 termios
.c_cc
[VSTOP
] = 023; /* ^S */
937 termios
.c_cc
[VSUSP
] = 032; /* ^Z */
938 termios
.c_cc
[VLNEXT
] = 026; /* ^V */
939 termios
.c_cc
[VWERASE
] = 027; /* ^W */
940 termios
.c_cc
[VREPRINT
] = 022; /* ^R */
941 termios
.c_cc
[VEOL
] = 0;
942 termios
.c_cc
[VEOL2
] = 0;
944 termios
.c_cc
[VTIME
] = 0;
945 termios
.c_cc
[VMIN
] = 1;
947 r
= RET_NERRNO(tcsetattr(fd
, TCSANOW
, &termios
));
949 log_debug_errno(r
, "Failed to set terminal parameters: %m");
952 /* Just in case, flush all crap out */
953 (void) tcflush(fd
, TCIOFLUSH
);
958 int terminal_reset_ansi_seq(int fd
) {
963 if (getenv_terminal_is_dumb())
966 r
= fd_nonblock(fd
, true);
968 return log_debug_errno(r
, "Failed to set terminal to non-blocking mode: %m");
970 k
= loop_write_full(fd
,
971 "\033[!p" /* soft terminal reset */
972 "\033]104\007" /* reset colors */
973 "\033[?7h" /* enable line-wrapping */
974 "\033[1G" /* place cursor at beginning of current line */
975 "\033[0J", /* erase till end of screen */
977 100 * USEC_PER_MSEC
);
979 log_debug_errno(k
, "Failed to reset terminal through ANSI sequences: %m");
982 r
= fd_nonblock(fd
, false);
984 log_debug_errno(r
, "Failed to set terminal back to blocking mode: %m");
987 return k
< 0 ? k
: r
;
990 void reset_dev_console_fd(int fd
, bool switch_to_text
) {
995 _cleanup_close_
int lock_fd
= lock_dev_console();
997 log_debug_errno(lock_fd
, "Failed to lock /dev/console, ignoring: %m");
999 r
= terminal_reset_ioctl(fd
, switch_to_text
);
1001 log_warning_errno(r
, "Failed to reset /dev/console, ignoring: %m");
1003 unsigned rows
, cols
;
1004 r
= proc_cmdline_tty_size("/dev/console", &rows
, &cols
);
1006 log_warning_errno(r
, "Failed to get /dev/console size, ignoring: %m");
1008 r
= terminal_set_size_fd(fd
, NULL
, rows
, cols
);
1010 log_warning_errno(r
, "Failed to set configured terminal size on /dev/console, ignoring: %m");
1012 (void) terminal_fix_size(fd
, fd
);
1014 r
= terminal_reset_ansi_seq(fd
);
1016 log_warning_errno(r
, "Failed to reset /dev/console using ANSI sequences, ignoring: %m");
1019 int lock_dev_console(void) {
1020 _cleanup_close_
int fd
= -EBADF
;
1023 /* NB: We do not use O_NOFOLLOW here, because some container managers might place a symlink to some
1024 * pty in /dev/console, in which case it should be fine to lock the target TTY. */
1025 fd
= open_terminal("/dev/console", O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
1029 r
= lock_generic(fd
, LOCK_BSD
, LOCK_EX
);
1036 int make_console_stdio(void) {
1039 /* Make /dev/console the controlling terminal and stdin/stdout/stderr, if we can. If we can't use
1040 * /dev/null instead. This is particularly useful if /dev/console is turned off, e.g. if console=null
1041 * is specified on the kernel command line. */
1043 fd
= acquire_terminal("/dev/console", ACQUIRE_TERMINAL_FORCE
|ACQUIRE_TERMINAL_PERMISSIVE
, USEC_INFINITY
);
1045 log_warning_errno(fd
, "Failed to acquire terminal, using /dev/null stdin/stdout/stderr instead: %m");
1047 r
= make_null_stdio();
1049 return log_error_errno(r
, "Failed to make /dev/null stdin/stdout/stderr: %m");
1052 reset_dev_console_fd(fd
, /* switch_to_text= */ true);
1054 r
= rearrange_stdio(fd
, fd
, fd
); /* This invalidates 'fd' both on success and on failure. */
1056 return log_error_errno(r
, "Failed to make terminal stdin/stdout/stderr: %m");
1059 reset_terminal_feature_caches();
1063 static int vtnr_from_tty_raw(const char *tty
, unsigned *ret
) {
1066 tty
= skip_dev_prefix(tty
);
1068 const char *e
= startswith(tty
, "tty");
1072 return safe_atou(e
, ret
);
1075 int vtnr_from_tty(const char *tty
) {
1081 r
= vtnr_from_tty_raw(tty
, &u
);
1084 if (!vtnr_is_valid(u
))
1090 bool tty_is_vc(const char *tty
) {
1093 /* NB: for >= 0 values no range check is conducted here, on the assumption that the caller will
1094 * either extract vtnr through vtnr_from_tty() later where ERANGE would be reported, or doesn't care
1095 * about whether it's strictly valid, but only asking "does this fall into the vt category?", for which
1096 * "yes" seems to be a better answer. */
1098 return vtnr_from_tty_raw(tty
, /* ret = */ NULL
) >= 0;
1101 bool tty_is_console(const char *tty
) {
1104 return streq(skip_dev_prefix(tty
), "console");
1107 int resolve_dev_console(char **ret
) {
1112 /* Resolve where /dev/console is pointing to. If /dev/console is a symlink (like in container
1113 * managers), we'll just resolve the symlink. If it's a real device node, we'll use if
1114 * /sys/class/tty/tty0/active, but only if /sys/ is actually ours (i.e. not read-only-mounted which
1115 * is a sign for container setups). */
1117 _cleanup_free_
char *chased
= NULL
;
1118 r
= chase("/dev/console", /* root= */ NULL
, /* flags= */ 0, &chased
, /* ret_fd= */ NULL
);
1121 if (!path_equal(chased
, "/dev/console")) {
1122 *ret
= TAKE_PTR(chased
);
1126 r
= path_is_read_only_fs("/sys");
1132 _cleanup_free_
char *active
= NULL
;
1133 r
= read_one_line_file("/sys/class/tty/console/active", &active
);
1137 /* If multiple log outputs are configured the last one is what /dev/console points to */
1138 const char *tty
= strrchr(active
, ' ');
1144 if (streq(tty
, "tty0")) {
1145 active
= mfree(active
);
1147 /* Get the active VC (e.g. tty1) */
1148 r
= read_one_line_file("/sys/class/tty/tty0/active", &active
);
1155 _cleanup_free_
char *path
= NULL
;
1156 path
= path_join("/dev", tty
);
1160 *ret
= TAKE_PTR(path
);
1164 int get_kernel_consoles(char ***ret
) {
1165 _cleanup_strv_free_
char **l
= NULL
;
1166 _cleanup_free_
char *line
= NULL
;
1171 /* If /sys/ is mounted read-only this means we are running in some kind of container environment.
1172 * In that case /sys/ would reflect the host system, not us, hence ignore the data we can read from it. */
1173 if (path_is_read_only_fs("/sys") > 0)
1176 r
= read_one_line_file("/sys/class/tty/console/active", &line
);
1180 for (const char *p
= line
;;) {
1181 _cleanup_free_
char *tty
= NULL
, *path
= NULL
;
1183 r
= extract_first_word(&p
, &tty
, NULL
, 0);
1189 if (streq(tty
, "tty0")) {
1191 r
= read_one_line_file("/sys/class/tty/tty0/active", &tty
);
1196 path
= path_join("/dev", tty
);
1200 if (access(path
, F_OK
) < 0) {
1201 log_debug_errno(errno
, "Console device %s is not accessible, skipping: %m", path
);
1205 r
= strv_consume(&l
, TAKE_PTR(path
));
1210 if (strv_isempty(l
)) {
1211 log_debug("No devices found for system console");
1216 return strv_length(*ret
);
1219 r
= strv_extend(&l
, "/dev/console");
1227 bool tty_is_vc_resolve(const char *tty
) {
1228 _cleanup_free_
char *resolved
= NULL
;
1232 if (streq(skip_dev_prefix(tty
), "console")) {
1233 if (resolve_dev_console(&resolved
) < 0)
1239 return tty_is_vc(tty
);
1242 int fd_columns(int fd
) {
1243 struct winsize ws
= {};
1248 if (ioctl(fd
, TIOCGWINSZ
, &ws
) < 0)
1252 return -ENODATA
; /* some tty types come up with invalid row/column initially, return a recognizable error for that */
1257 int getenv_columns(void) {
1260 const char *e
= getenv("COLUMNS");
1265 r
= safe_atou_bounded(e
, 1, USHRT_MAX
, &c
);
1272 unsigned columns(void) {
1274 if (cached_columns
> 0)
1275 return cached_columns
;
1277 int c
= getenv_columns();
1279 c
= fd_columns(STDOUT_FILENO
);
1287 return cached_columns
;
1290 int fd_lines(int fd
) {
1291 struct winsize ws
= {};
1296 if (ioctl(fd
, TIOCGWINSZ
, &ws
) < 0)
1300 return -ENODATA
; /* some tty types come up with invalid row/column initially, return a recognizable error for that */
1305 unsigned lines(void) {
1309 if (cached_lines
> 0)
1310 return cached_lines
;
1313 e
= getenv("LINES");
1315 (void) safe_atoi(e
, &l
);
1317 if (l
<= 0 || l
> USHRT_MAX
) {
1318 l
= fd_lines(STDOUT_FILENO
);
1324 return cached_lines
;
1327 int terminal_set_size_fd(int fd
, const char *ident
, unsigned rows
, unsigned cols
) {
1335 if (rows
== UINT_MAX
&& cols
== UINT_MAX
)
1338 if (ioctl(fd
, TIOCGWINSZ
, &ws
) < 0)
1339 return log_debug_errno(errno
,
1340 "TIOCGWINSZ ioctl for getting %s size failed, not setting terminal size: %m",
1343 if (rows
== UINT_MAX
)
1345 else if (rows
> USHRT_MAX
)
1348 if (cols
== UINT_MAX
)
1350 else if (cols
> USHRT_MAX
)
1353 if (rows
== ws
.ws_row
&& cols
== ws
.ws_col
)
1359 if (ioctl(fd
, TIOCSWINSZ
, &ws
) < 0)
1360 return log_debug_errno(errno
, "TIOCSWINSZ ioctl for setting %s size failed: %m", ident
);
1365 int proc_cmdline_tty_size(const char *tty
, unsigned *ret_rows
, unsigned *ret_cols
) {
1366 _cleanup_free_
char *rowskey
= NULL
, *rowsvalue
= NULL
, *colskey
= NULL
, *colsvalue
= NULL
;
1367 unsigned rows
= UINT_MAX
, cols
= UINT_MAX
;
1372 if (!ret_rows
&& !ret_cols
)
1375 tty
= skip_dev_prefix(tty
);
1376 if (path_startswith(tty
, "pts/"))
1377 return -EMEDIUMTYPE
;
1378 if (!in_charset(tty
, ALPHANUMERICAL
))
1379 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL
),
1380 "TTY name '%s' contains non-alphanumeric characters, not searching kernel cmdline for size.", tty
);
1382 rowskey
= strjoin("systemd.tty.rows.", tty
);
1386 colskey
= strjoin("systemd.tty.columns.", tty
);
1390 r
= proc_cmdline_get_key_many(/* flags = */ 0,
1391 rowskey
, &rowsvalue
,
1392 colskey
, &colsvalue
);
1394 return log_debug_errno(r
, "Failed to read TTY size of %s from kernel cmdline: %m", tty
);
1397 r
= safe_atou(rowsvalue
, &rows
);
1399 return log_debug_errno(r
, "Failed to parse %s=%s: %m", rowskey
, rowsvalue
);
1403 r
= safe_atou(colsvalue
, &cols
);
1405 return log_debug_errno(r
, "Failed to parse %s=%s: %m", colskey
, colsvalue
);
1413 return rows
!= UINT_MAX
|| cols
!= UINT_MAX
;
1416 /* intended to be used as a SIGWINCH sighandler */
1417 void columns_lines_cache_reset(int signum
) {
1422 void reset_terminal_feature_caches(void) {
1427 cached_on_dev_null
= -1;
1429 reset_ansi_feature_caches();
1434 /* We check both stdout and stderr, so that situations where pipes on the shell are used are reliably
1435 * recognized, regardless if only the output or the errors are piped to some place. Since on_tty() is generally
1436 * used to default to a safer, non-interactive, non-color mode of operation it's probably good to be defensive
1437 * here, and check for both. Note that we don't check for STDIN_FILENO, because it should fine to use fancy
1438 * terminal functionality when outputting stuff, even if the input is piped to us. */
1440 if (cached_on_tty
< 0)
1442 isatty_safe(STDOUT_FILENO
) &&
1443 isatty_safe(STDERR_FILENO
);
1445 return cached_on_tty
;
1448 int getttyname_malloc(int fd
, char **ret
) {
1449 char path
[PATH_MAX
]; /* PATH_MAX is counted *with* the trailing NUL byte */
1455 r
= ttyname_r(fd
, path
, sizeof path
); /* positive error */
1458 return -ENAMETOOLONG
;
1462 return strdup_to(ret
, skip_dev_prefix(path
));
1465 int getttyname_harder(int fd
, char **ret
) {
1466 _cleanup_free_
char *s
= NULL
;
1469 r
= getttyname_malloc(fd
, &s
);
1473 if (streq(s
, "tty"))
1474 return get_ctty(0, NULL
, ret
);
1480 int get_ctty_devnr(pid_t pid
, dev_t
*ret
) {
1481 _cleanup_free_
char *line
= NULL
;
1482 unsigned long ttynr
;
1488 p
= procfs_file_alloca(pid
, "stat");
1489 r
= read_one_line_file(p
, &line
);
1493 p
= strrchr(line
, ')');
1503 "%*d " /* session */
1508 if (devnum_is_zero(ttynr
))
1512 *ret
= (dev_t
) ttynr
;
1517 int get_ctty(pid_t pid
, dev_t
*ret_devnr
, char **ret
) {
1518 char pty
[STRLEN("/dev/pts/") + DECIMAL_STR_MAX(dev_t
) + 1];
1519 _cleanup_free_
char *buf
= NULL
;
1520 const char *fn
= NULL
, *w
;
1524 r
= get_ctty_devnr(pid
, &devnr
);
1528 r
= device_path_make_canonical(S_IFCHR
, devnr
, &buf
);
1532 if (r
!= -ENOENT
) /* No symlink for this in /dev/char/? */
1535 /* Maybe this is PTY? PTY devices are not listed in /dev/char/, as they don't follow the
1536 * Linux device model and hence device_path_make_canonical() doesn't work for them. Let's
1537 * assume this is a PTY for a moment, and check if the device node this would then map to in
1538 * /dev/pts/ matches the one we are looking for. This way we don't have to hardcode the major
1539 * number (which is 136 btw), but we still rely on the fact that PTY numbers map directly to
1540 * the minor number of the pty. */
1541 xsprintf(pty
, "/dev/pts/%u", minor(devnr
));
1543 if (stat(pty
, &st
) < 0) {
1544 if (errno
!= ENOENT
)
1547 } else if (S_ISCHR(st
.st_mode
) && devnr
== st
.st_rdev
) /* Bingo! */
1551 /* Doesn't exist, or not a PTY? Probably something similar to the PTYs which have no
1552 * symlink in /dev/char/. Let's return something vaguely useful. */
1553 r
= device_path_make_major_minor(S_IFCHR
, devnr
, &buf
);
1562 w
= path_startswith(fn
, "/dev/");
1567 r
= strdup_to(ret
, w
);
1578 int ptsname_malloc(int fd
, char **ret
) {
1582 for (size_t l
= 50;;) {
1583 _cleanup_free_
char *c
= NULL
;
1589 if (ptsname_r(fd
, c
, l
) >= 0) {
1593 if (errno
!= ERANGE
)
1596 if (!MUL_ASSIGN_SAFE(&l
, 2))
1601 int openpt_allocate(int flags
, char **ret_peer_path
) {
1602 _cleanup_close_
int fd
= -EBADF
;
1605 fd
= posix_openpt(flags
|O_NOCTTY
|O_CLOEXEC
);
1609 _cleanup_free_
char *p
= NULL
;
1610 if (ret_peer_path
) {
1611 r
= ptsname_malloc(fd
, &p
);
1615 if (!path_startswith(p
, "/dev/pts/"))
1619 if (unlockpt(fd
) < 0)
1623 *ret_peer_path
= TAKE_PTR(p
);
1628 static int ptsname_namespace(int pty
, char **ret
) {
1634 /* Like ptsname(), but doesn't assume that the path is
1635 * accessible in the local namespace. */
1637 if (ioctl(pty
, TIOCGPTN
, &no
) < 0)
1643 if (asprintf(ret
, "/dev/pts/%i", no
) < 0)
1649 int openpt_allocate_in_namespace(
1650 const PidRef
*pidref
,
1652 char **ret_peer_path
) {
1654 _cleanup_close_
int pidnsfd
= -EBADF
, mntnsfd
= -EBADF
, usernsfd
= -EBADF
, rootfd
= -EBADF
, fd
= -EBADF
;
1655 _cleanup_close_pair_
int pair
[2] = EBADF_PAIR
;
1658 r
= pidref_namespace_open(pidref
, &pidnsfd
, &mntnsfd
, /* ret_netns_fd = */ NULL
, &usernsfd
, &rootfd
);
1662 if (socketpair(AF_UNIX
, SOCK_DGRAM
|SOCK_CLOEXEC
, 0, pair
) < 0)
1668 /* except_fds= */ NULL
,
1669 /* n_except_fds= */ 0,
1670 FORK_RESET_SIGNALS
|FORK_DEATHSIG_SIGKILL
|FORK_WAIT
,
1673 /* netns_fd= */ -EBADF
,
1676 /* ret_pid= */ NULL
);
1680 pair
[0] = safe_close(pair
[0]);
1682 fd
= openpt_allocate(flags
, /* ret_peer_path= */ NULL
);
1684 _exit(EXIT_FAILURE
);
1686 if (send_one_fd(pair
[1], fd
, 0) < 0)
1687 _exit(EXIT_FAILURE
);
1689 _exit(EXIT_SUCCESS
);
1692 pair
[1] = safe_close(pair
[1]);
1694 fd
= receive_one_fd(pair
[0], 0);
1698 if (ret_peer_path
) {
1699 r
= ptsname_namespace(fd
, ret_peer_path
);
1707 static bool on_dev_null(void) {
1708 struct stat dst
, ost
, est
;
1710 if (cached_on_dev_null
>= 0)
1711 return cached_on_dev_null
;
1713 if (stat("/dev/null", &dst
) < 0 || fstat(STDOUT_FILENO
, &ost
) < 0 || fstat(STDERR_FILENO
, &est
) < 0)
1714 cached_on_dev_null
= false;
1716 cached_on_dev_null
= stat_inode_same(&dst
, &ost
) && stat_inode_same(&dst
, &est
);
1718 return cached_on_dev_null
;
1721 bool getenv_terminal_is_dumb(void) {
1728 return streq(e
, "dumb");
1731 bool terminal_is_dumb(void) {
1732 if (!on_tty() && !on_dev_null())
1735 return getenv_terminal_is_dumb();
1738 bool dev_console_colors_enabled(void) {
1739 _cleanup_free_
char *s
= NULL
;
1742 /* Returns true if we assume that color is supported on /dev/console.
1744 * For that we first check if we explicitly got told to use colors or not, by checking $SYSTEMD_COLORS. If that
1745 * isn't set we check whether PID 1 has $TERM set, and if not, whether TERM is set on the kernel command
1746 * line. If we find $TERM set we assume color if it's not set to "dumb", similarly to how regular
1747 * colors_enabled() operates. */
1749 m
= parse_systemd_colors();
1753 if (getenv("NO_COLOR"))
1756 if (getenv_for_pid(1, "TERM", &s
) <= 0)
1757 (void) proc_cmdline_get_key("TERM", 0, &s
);
1759 return !streq_ptr(s
, "dumb");
1762 int vt_restore(int fd
) {
1764 static const struct vt_mode mode
= {
1772 if (!isatty_safe(fd
))
1773 return log_debug_errno(SYNTHETIC_ERRNO(ENOTTY
), "Asked to restore the VT for an fd that does not refer to a terminal.");
1775 if (ioctl(fd
, KDSETMODE
, KD_TEXT
) < 0)
1776 RET_GATHER(ret
, log_debug_errno(errno
, "Failed to set VT to text mode, ignoring: %m"));
1778 r
= vt_reset_keyboard(fd
);
1780 RET_GATHER(ret
, log_debug_errno(r
, "Failed to reset keyboard mode, ignoring: %m"));
1782 if (ioctl(fd
, VT_SETMODE
, &mode
) < 0)
1783 RET_GATHER(ret
, log_debug_errno(errno
, "Failed to set VT_AUTO mode, ignoring: %m"));
1785 r
= fchmod_and_chown(fd
, TTY_MODE
, 0, GID_INVALID
);
1787 RET_GATHER(ret
, log_debug_errno(r
, "Failed to chmod()/chown() VT, ignoring: %m"));
1792 int vt_release(int fd
, bool restore
) {
1795 /* This function releases the VT by acknowledging the VT-switch signal
1796 * sent by the kernel and optionally reset the VT in text and auto
1797 * VT-switching modes. */
1799 if (!isatty_safe(fd
))
1800 return log_debug_errno(SYNTHETIC_ERRNO(ENOTTY
), "Asked to release the VT for an fd that does not refer to a terminal.");
1802 if (ioctl(fd
, VT_RELDISP
, 1) < 0)
1806 return vt_restore(fd
);
1811 void get_log_colors(int priority
, const char **on
, const char **off
, const char **highlight
) {
1812 /* Note that this will initialize output variables only when there's something to output.
1813 * The caller must pre-initialize to "" or NULL as appropriate. */
1815 if (priority
<= LOG_ERR
) {
1817 *on
= ansi_highlight_red();
1819 *off
= ansi_normal();
1821 *highlight
= ansi_highlight();
1823 } else if (priority
<= LOG_WARNING
) {
1825 *on
= ansi_highlight_yellow();
1827 *off
= ansi_normal();
1829 *highlight
= ansi_highlight();
1831 } else if (priority
<= LOG_NOTICE
) {
1833 *on
= ansi_highlight();
1835 *off
= ansi_normal();
1837 *highlight
= ansi_highlight_red();
1839 } else if (priority
>= LOG_DEBUG
) {
1843 *off
= ansi_normal();
1845 *highlight
= ansi_highlight_red();
1849 int terminal_set_cursor_position(int fd
, unsigned row
, unsigned column
) {
1852 char cursor_position
[STRLEN("\x1B[" ";" "H") + DECIMAL_STR_MAX(unsigned) * 2 + 1];
1853 xsprintf(cursor_position
, "\x1B[%u;%uH", row
, column
);
1855 return loop_write(fd
, cursor_position
, SIZE_MAX
);
1858 static int terminal_verify_same(int input_fd
, int output_fd
) {
1859 assert(input_fd
>= 0);
1860 assert(output_fd
>= 0);
1862 /* Validates that the specified fds reference the same TTY */
1864 if (input_fd
!= output_fd
) {
1866 if (fstat(input_fd
, &sti
) < 0)
1869 if (!S_ISCHR(sti
.st_mode
)) /* TTYs are character devices */
1873 if (fstat(output_fd
, &sto
) < 0)
1876 if (!S_ISCHR(sto
.st_mode
))
1879 if (sti
.st_rdev
!= sto
.st_rdev
)
1883 if (!isatty_safe(input_fd
)) /* The check above was just for char device, but now let's ensure it's actually a tty */
1889 typedef enum CursorPositionState
{
1894 } CursorPositionState
;
1896 typedef struct CursorPositionContext
{
1897 CursorPositionState state
;
1898 unsigned row
, column
;
1899 } CursorPositionContext
;
1901 static int scan_cursor_position_response(
1902 CursorPositionContext
*context
,
1905 size_t *ret_processed
) {
1909 assert(ret_processed
);
1911 for (size_t i
= 0; i
< size
; i
++) {
1914 switch (context
->state
) {
1917 context
->state
= c
== '\x1B' ? CURSOR_ESCAPE
: CURSOR_TEXT
;
1921 context
->state
= c
== '[' ? CURSOR_ROW
: CURSOR_TEXT
;
1926 context
->state
= context
->row
> 0 ? CURSOR_COLUMN
: CURSOR_TEXT
;
1928 int d
= undecchar(c
);
1930 /* We read a decimal character, let's suffix it to the number we so far read,
1931 * but let's do an overflow check first. */
1932 if (d
< 0 || context
->row
> (UINT_MAX
-d
)/10)
1933 context
->state
= CURSOR_TEXT
;
1935 context
->row
= context
->row
* 10 + d
;
1941 if (context
->column
> 0) {
1942 *ret_processed
= i
+ 1;
1943 return 1; /* success! */
1946 context
->state
= CURSOR_TEXT
;
1948 int d
= undecchar(c
);
1950 /* As above, add the decimal character to our column number */
1951 if (d
< 0 || context
->column
> (UINT_MAX
-d
)/10)
1952 context
->state
= CURSOR_TEXT
;
1954 context
->column
= context
->column
* 10 + d
;
1960 /* Reset any positions we might have picked up */
1961 if (IN_SET(context
->state
, CURSOR_TEXT
, CURSOR_ESCAPE
))
1962 context
->row
= context
->column
= 0;
1965 *ret_processed
= size
;
1966 return 0; /* all good, but not enough data yet */
1969 int terminal_get_cursor_position(
1973 unsigned *ret_column
) {
1975 _cleanup_close_
int nonblock_input_fd
= -EBADF
;
1978 assert(input_fd
>= 0);
1979 assert(output_fd
>= 0);
1981 if (terminal_is_dumb())
1984 r
= terminal_verify_same(input_fd
, output_fd
);
1986 return log_debug_errno(r
, "Called with distinct input/output fds: %m");
1988 struct termios old_termios
;
1989 if (tcgetattr(input_fd
, &old_termios
) < 0)
1990 return log_debug_errno(errno
, "Failed to get terminal settings: %m");
1992 struct termios new_termios
= old_termios
;
1993 termios_disable_echo(&new_termios
);
1995 if (tcsetattr(input_fd
, TCSANOW
, &new_termios
) < 0)
1996 return log_debug_errno(errno
, "Failed to set new terminal settings: %m");
1998 /* Request cursor position (DSR/CPR) */
1999 r
= loop_write(output_fd
, "\x1B[6n", SIZE_MAX
);
2003 /* Open a 2nd input fd, in non-blocking mode, so that we won't ever hang in read() should someone
2004 * else process the POLLIN. */
2006 nonblock_input_fd
= r
= fd_reopen(input_fd
, O_RDONLY
|O_CLOEXEC
|O_NONBLOCK
|O_NOCTTY
);
2010 usec_t end
= usec_add(now(CLOCK_MONOTONIC
), CONSOLE_REPLY_WAIT_USEC
);
2011 char buf
[STRLEN("\x1B[1;1R")]; /* The shortest valid reply possible */
2012 size_t buf_full
= 0;
2013 CursorPositionContext context
= {};
2015 for (bool first
= true;; first
= false) {
2016 if (buf_full
== 0) {
2017 usec_t n
= now(CLOCK_MONOTONIC
);
2023 r
= fd_wait_for_event(nonblock_input_fd
, POLLIN
, usec_sub_unsigned(end
, n
));
2031 /* On the first try, read multiple characters, i.e. the shortest valid
2032 * reply. Afterwards read byte-wise, since we don't want to read too much, and
2033 * unnecessarily drop too many characters from the input queue. */
2034 ssize_t l
= read(nonblock_input_fd
, buf
, first
? sizeof(buf
) : 1);
2036 if (errno
== EAGAIN
)
2043 assert((size_t) l
<= sizeof(buf
));
2048 r
= scan_cursor_position_response(&context
, buf
, buf_full
, &processed
);
2052 assert(processed
<= buf_full
);
2053 buf_full
-= processed
;
2054 memmove(buf
, buf
+ processed
, buf_full
);
2057 /* Superficial validity check */
2058 if (context
.row
>= 32766 || context
.column
>= 32766) {
2064 *ret_row
= context
.row
;
2066 *ret_column
= context
.column
;
2074 /* We ignore failure here and in similar cases below. We already got a reply and if cleanup fails,
2075 * this doesn't change the validity of the result. */
2076 (void) tcsetattr(input_fd
, TCSANOW
, &old_termios
);
2080 int terminal_reset_defensive(int fd
, TerminalResetFlags flags
) {
2084 assert(!FLAGS_SET(flags
, TERMINAL_RESET_AVOID_ANSI_SEQ
|TERMINAL_RESET_FORCE_ANSI_SEQ
));
2086 /* Resets the terminal comprehensively, i.e. via both ioctl()s and via ANSI sequences, but do so only
2087 * if $TERM is unset or set to "dumb" */
2089 if (!isatty_safe(fd
))
2092 RET_GATHER(r
, terminal_reset_ioctl(fd
, FLAGS_SET(flags
, TERMINAL_RESET_SWITCH_TO_TEXT
)));
2094 if (!FLAGS_SET(flags
, TERMINAL_RESET_AVOID_ANSI_SEQ
) &&
2095 (FLAGS_SET(flags
, TERMINAL_RESET_FORCE_ANSI_SEQ
) || !getenv_terminal_is_dumb()))
2096 RET_GATHER(r
, terminal_reset_ansi_seq(fd
));
2101 int terminal_reset_defensive_locked(int fd
, TerminalResetFlags flags
) {
2104 _cleanup_close_
int lock_fd
= lock_dev_console();
2106 log_debug_errno(lock_fd
, "Failed to acquire lock for /dev/console, ignoring: %m");
2108 return terminal_reset_defensive(fd
, flags
);
2111 void termios_disable_echo(struct termios
*termios
) {
2114 termios
->c_lflag
&= ~(ICANON
|ECHO
);
2115 termios
->c_cc
[VMIN
] = 1;
2116 termios
->c_cc
[VTIME
] = 0;
2119 typedef enum BackgroundColorState
{
2123 BACKGROUND_FIRST_ONE
,
2124 BACKGROUND_SECOND_ONE
,
2125 BACKGROUND_SEMICOLON
,
2132 BACKGROUND_STRING_TERMINATOR
,
2133 } BackgroundColorState
;
2135 typedef struct BackgroundColorContext
{
2136 BackgroundColorState state
;
2137 uint32_t red
, green
, blue
;
2138 unsigned red_bits
, green_bits
, blue_bits
;
2139 } BackgroundColorContext
;
2141 static int scan_background_color_response(
2142 BackgroundColorContext
*context
,
2145 size_t *ret_processed
) {
2149 assert(ret_processed
);
2151 for (size_t i
= 0; i
< size
; i
++) {
2154 switch (context
->state
) {
2156 case BACKGROUND_TEXT
:
2157 context
->state
= c
== '\x1B' ? BACKGROUND_ESCAPE
: BACKGROUND_TEXT
;
2160 case BACKGROUND_ESCAPE
:
2161 context
->state
= c
== ']' ? BACKGROUND_BRACKET
: BACKGROUND_TEXT
;
2164 case BACKGROUND_BRACKET
:
2165 context
->state
= c
== '1' ? BACKGROUND_FIRST_ONE
: BACKGROUND_TEXT
;
2168 case BACKGROUND_FIRST_ONE
:
2169 context
->state
= c
== '1' ? BACKGROUND_SECOND_ONE
: BACKGROUND_TEXT
;
2172 case BACKGROUND_SECOND_ONE
:
2173 context
->state
= c
== ';' ? BACKGROUND_SEMICOLON
: BACKGROUND_TEXT
;
2176 case BACKGROUND_SEMICOLON
:
2177 context
->state
= c
== 'r' ? BACKGROUND_R
: BACKGROUND_TEXT
;
2181 context
->state
= c
== 'g' ? BACKGROUND_G
: BACKGROUND_TEXT
;
2185 context
->state
= c
== 'b' ? BACKGROUND_B
: BACKGROUND_TEXT
;
2189 context
->state
= c
== ':' ? BACKGROUND_RED
: BACKGROUND_TEXT
;
2192 case BACKGROUND_RED
:
2194 context
->state
= context
->red_bits
> 0 ? BACKGROUND_GREEN
: BACKGROUND_TEXT
;
2196 int d
= unhexchar(c
);
2197 if (d
< 0 || context
->red_bits
>= sizeof(context
->red
)*8)
2198 context
->state
= BACKGROUND_TEXT
;
2200 context
->red
= (context
->red
<< 4) | d
;
2201 context
->red_bits
+= 4;
2206 case BACKGROUND_GREEN
:
2208 context
->state
= context
->green_bits
> 0 ? BACKGROUND_BLUE
: BACKGROUND_TEXT
;
2210 int d
= unhexchar(c
);
2211 if (d
< 0 || context
->green_bits
>= sizeof(context
->green
)*8)
2212 context
->state
= BACKGROUND_TEXT
;
2214 context
->green
= (context
->green
<< 4) | d
;
2215 context
->green_bits
+= 4;
2220 case BACKGROUND_BLUE
:
2222 if (context
->blue_bits
> 0) {
2223 *ret_processed
= i
+ 1;
2224 return 1; /* success! */
2227 context
->state
= BACKGROUND_TEXT
;
2228 } else if (c
== '\x1b')
2229 context
->state
= context
->blue_bits
> 0 ? BACKGROUND_STRING_TERMINATOR
: BACKGROUND_TEXT
;
2231 int d
= unhexchar(c
);
2232 if (d
< 0 || context
->blue_bits
>= sizeof(context
->blue
)*8)
2233 context
->state
= BACKGROUND_TEXT
;
2235 context
->blue
= (context
->blue
<< 4) | d
;
2236 context
->blue_bits
+= 4;
2241 case BACKGROUND_STRING_TERMINATOR
:
2243 *ret_processed
= i
+ 1;
2244 return 1; /* success! */
2247 context
->state
= c
== ']' ? BACKGROUND_ESCAPE
: BACKGROUND_TEXT
;
2252 /* Reset any colors we might have picked up */
2253 if (IN_SET(context
->state
, BACKGROUND_TEXT
, BACKGROUND_ESCAPE
)) {
2255 context
->red
= context
->green
= context
->blue
= 0;
2256 context
->red_bits
= context
->green_bits
= context
->blue_bits
= 0;
2260 *ret_processed
= size
;
2261 return 0; /* all good, but not enough data yet */
2264 int get_default_background_color(double *ret_red
, double *ret_green
, double *ret_blue
) {
2271 if (!colors_enabled())
2274 r
= terminal_verify_same(STDIN_FILENO
, STDOUT_FILENO
);
2278 if (streq_ptr(getenv("TERM"), "linux")) {
2279 /* Linux console is black */
2280 *ret_red
= *ret_green
= *ret_blue
= 0.0;
2284 /* Open a 2nd input fd, in non-blocking mode, so that we won't ever hang in read()
2285 * should someone else process the POLLIN. Do all subsequent operations on the new fd. */
2286 _cleanup_close_
int nonblock_input_fd
= r
= fd_reopen(STDIN_FILENO
, O_RDONLY
|O_CLOEXEC
|O_NONBLOCK
|O_NOCTTY
);
2290 struct termios old_termios
;
2291 if (tcgetattr(nonblock_input_fd
, &old_termios
) < 0)
2294 struct termios new_termios
= old_termios
;
2295 termios_disable_echo(&new_termios
);
2297 if (tcsetattr(nonblock_input_fd
, TCSANOW
, &new_termios
) < 0)
2300 r
= loop_write(STDOUT_FILENO
, ANSI_OSC
"11;?" ANSI_ST
, SIZE_MAX
);
2304 usec_t end
= usec_add(now(CLOCK_MONOTONIC
), CONSOLE_REPLY_WAIT_USEC
);
2305 char buf
[STRLEN(ANSI_OSC
"11;rgb:0/0/0" ANSI_ST
)]; /* shortest possible reply */
2306 size_t buf_full
= 0;
2307 BackgroundColorContext context
= {};
2309 for (bool first
= true;; first
= false) {
2310 if (buf_full
== 0) {
2311 usec_t n
= now(CLOCK_MONOTONIC
);
2317 r
= fd_wait_for_event(nonblock_input_fd
, POLLIN
, usec_sub_unsigned(end
, n
));
2325 /* On the first try, read multiple characters, i.e. the shortest valid
2326 * reply. Afterwards read byte-wise, since we don't want to read too much, and
2327 * unnecessarily drop too many characters from the input queue. */
2328 ssize_t l
= read(nonblock_input_fd
, buf
, first
? sizeof(buf
) : 1);
2330 if (errno
== EAGAIN
)
2336 assert((size_t) l
<= sizeof(buf
));
2341 r
= scan_background_color_response(&context
, buf
, buf_full
, &processed
);
2345 assert(processed
<= buf_full
);
2346 buf_full
-= processed
;
2347 memmove(buf
, buf
+ processed
, buf_full
);
2350 assert(context
.red_bits
> 0);
2351 *ret_red
= (double) context
.red
/ ((UINT64_C(1) << context
.red_bits
) - 1);
2352 assert(context
.green_bits
> 0);
2353 *ret_green
= (double) context
.green
/ ((UINT64_C(1) << context
.green_bits
) - 1);
2354 assert(context
.blue_bits
> 0);
2355 *ret_blue
= (double) context
.blue
/ ((UINT64_C(1) << context
.blue_bits
) - 1);
2362 (void) tcsetattr(nonblock_input_fd
, TCSANOW
, &old_termios
);
2366 int terminal_get_size_by_dsr(
2370 unsigned *ret_columns
) {
2374 assert(input_fd
>= 0);
2375 assert(output_fd
>= 0);
2377 /* Tries to determine the terminal dimension by means of ANSI sequences rather than TIOCGWINSZ
2378 * ioctl(). Why bother with this? The ioctl() information is often incorrect on serial terminals
2379 * (since there's no handshake or protocol to determine the right dimensions in RS232), but since the
2380 * ANSI sequences are interpreted by the final terminal instead of an intermediary tty driver they
2381 * should be more accurate.
2383 * Unfortunately there's no direct ANSI sequence to query terminal dimensions. But we can hack around
2384 * it: we position the cursor briefly at an absolute location very far down and very far to the
2385 * right, and then read back where we actually ended up. Because cursor locations are capped at the
2386 * terminal width/height we should then see the right values. In order to not risk integer overflows
2387 * in terminal applications we'll use INT16_MAX-1 as location to jump to — hopefully a value that is
2388 * large enough for any real-life terminals, but small enough to not overflow anything or be
2389 * recognized as a "niche" value. (Note that the dimension fields in "struct winsize" are 16bit only,
2392 if (terminal_is_dumb())
2395 r
= terminal_verify_same(input_fd
, output_fd
);
2397 return log_debug_errno(r
, "Called with distinct input/output fds: %m");
2399 /* Open a 2nd input fd, in non-blocking mode, so that we won't ever hang in read()
2400 * should someone else process the POLLIN. Do all subsequent operations on the new fd. */
2401 _cleanup_close_
int nonblock_input_fd
= r
= fd_reopen(input_fd
, O_RDONLY
|O_CLOEXEC
|O_NONBLOCK
|O_NOCTTY
);
2405 struct termios old_termios
;
2406 if (tcgetattr(nonblock_input_fd
, &old_termios
) < 0)
2407 return log_debug_errno(errno
, "Failed to get terminal settings: %m");
2409 struct termios new_termios
= old_termios
;
2410 termios_disable_echo(&new_termios
);
2412 if (tcsetattr(nonblock_input_fd
, TCSANOW
, &new_termios
) < 0)
2413 return log_debug_errno(errno
, "Failed to set new terminal settings: %m");
2415 unsigned saved_row
= 0, saved_column
= 0;
2417 r
= loop_write(output_fd
,
2418 "\x1B[6n" /* Request cursor position (DSR/CPR) */
2419 "\x1B[32766;32766H" /* Position cursor really far to the right and to the bottom, but let's stay within the 16bit signed range */
2420 "\x1B[6n", /* Request cursor position again */
2425 usec_t end
= usec_add(now(CLOCK_MONOTONIC
), CONSOLE_REPLY_WAIT_USEC
);
2426 char buf
[STRLEN("\x1B[1;1R")]; /* The shortest valid reply possible */
2427 size_t buf_full
= 0;
2428 CursorPositionContext context
= {};
2430 for (bool first
= true;; first
= false) {
2431 if (buf_full
== 0) {
2432 usec_t n
= now(CLOCK_MONOTONIC
);
2438 r
= fd_wait_for_event(nonblock_input_fd
, POLLIN
, usec_sub_unsigned(end
, n
));
2446 /* On the first try, read multiple characters, i.e. the shortest valid
2447 * reply. Afterwards read byte-wise, since we don't want to read too much, and
2448 * unnecessarily drop too many characters from the input queue. */
2449 ssize_t l
= read(nonblock_input_fd
, buf
, first
? sizeof(buf
) : 1);
2451 if (errno
== EAGAIN
)
2458 assert((size_t) l
<= sizeof(buf
));
2463 r
= scan_cursor_position_response(&context
, buf
, buf_full
, &processed
);
2467 assert(processed
<= buf_full
);
2468 buf_full
-= processed
;
2469 memmove(buf
, buf
+ processed
, buf_full
);
2472 if (saved_row
== 0) {
2473 assert(saved_column
== 0);
2475 /* First sequence, this is the cursor position before we set it somewhere
2476 * into the void at the bottom right. Let's save where we are so that we can
2479 /* Superficial validity checks */
2480 if (context
.row
<= 0 || context
.column
<= 0 || context
.row
>= 32766 || context
.column
>= 32766) {
2485 saved_row
= context
.row
;
2486 saved_column
= context
.column
;
2489 context
= (CursorPositionContext
) {};
2491 /* Second sequence, this is the cursor position after we set it somewhere
2492 * into the void at the bottom right. */
2494 /* Superficial validity checks (no particular reason to check for < 4, it's
2495 * just a way to look for unreasonably small values) */
2496 if (context
.row
< 4 || context
.column
< 4 || context
.row
>= 32766 || context
.column
>= 32766) {
2502 *ret_rows
= context
.row
;
2504 *ret_columns
= context
.column
;
2513 /* Restore cursor position */
2514 if (saved_row
> 0 && saved_column
> 0)
2515 (void) terminal_set_cursor_position(output_fd
, saved_row
, saved_column
);
2516 (void) tcsetattr(nonblock_input_fd
, TCSANOW
, &old_termios
);
2521 int terminal_fix_size(int input_fd
, int output_fd
) {
2522 unsigned rows
, columns
;
2525 /* Tries to update the current terminal dimensions to the ones reported via ANSI sequences */
2527 r
= terminal_verify_same(input_fd
, output_fd
);
2531 struct winsize ws
= {};
2532 if (ioctl(output_fd
, TIOCGWINSZ
, &ws
) < 0)
2533 return log_debug_errno(errno
, "Failed to query terminal dimensions, ignoring: %m");
2535 r
= terminal_get_size_by_dsr(input_fd
, output_fd
, &rows
, &columns
);
2537 return log_debug_errno(r
, "Failed to acquire terminal dimensions via ANSI sequences, not adjusting terminal dimensions: %m");
2539 if (ws
.ws_row
== rows
&& ws
.ws_col
== columns
) {
2540 log_debug("Terminal dimensions reported via ANSI sequences match currently set terminal dimensions, not changing.");
2544 ws
.ws_col
= columns
;
2547 if (ioctl(output_fd
, TIOCSWINSZ
, &ws
) < 0)
2548 return log_debug_errno(errno
, "Failed to update terminal dimensions, ignoring: %m");
2550 log_debug("Fixed terminal dimensions to %ux%u based on ANSI sequence information.", columns
, rows
);
2554 #define MAX_TERMINFO_LENGTH 64
2555 /* python -c 'print("".join(hex(ord(i))[2:] for i in "name").upper())' */
2556 #define DCS_TERMINFO_Q ANSI_DCS "+q" "6E616D65" ANSI_ST
2557 /* The answer is either 0+r… (invalid) or 1+r… (OK). */
2558 #define DCS_TERMINFO_R0 ANSI_DCS "0+r" ANSI_ST
2559 #define DCS_TERMINFO_R1 ANSI_DCS "1+r" "6E616D65" "=" /* This is followed by Pt ST. */
2560 assert_cc(STRLEN(DCS_TERMINFO_R0
) <= STRLEN(DCS_TERMINFO_R1 ANSI_ST
));
2562 static int scan_terminfo_response(
2571 /* Check if we have enough space for the shortest possible answer. */
2572 if (size
< STRLEN(DCS_TERMINFO_R0
))
2575 /* Check if the terminating sequence is present */
2576 if (memcmp(buf
+ size
- STRLEN(ANSI_ST
), ANSI_ST
, STRLEN(ANSI_ST
)) != 0)
2579 if (size
<= STRLEN(DCS_TERMINFO_R1 ANSI_ST
))
2580 return -EINVAL
; /* The answer is invalid or empty */
2582 if (memcmp(buf
, DCS_TERMINFO_R1
, STRLEN(DCS_TERMINFO_R1
)) != 0)
2583 return -EINVAL
; /* The answer is not valid */
2585 _cleanup_free_
void *dec
= NULL
;
2587 r
= unhexmem_full(buf
+ STRLEN(DCS_TERMINFO_R1
), size
- STRLEN(DCS_TERMINFO_R1 ANSI_ST
),
2588 /* secure= */ false,
2593 assert(((const char *) dec
)[dec_size
] == '\0'); /* unhexmem appends NUL for our convenience */
2594 if (memchr(dec
, '\0', dec_size
) || string_has_cc(dec
, NULL
) || !filename_is_valid(dec
))
2597 *ret_name
= TAKE_PTR(dec
);
2601 int terminal_get_terminfo_by_dcs(int fd
, char **ret_name
) {
2607 /* Note: fd must be in non-blocking read-write mode! */
2609 struct termios old_termios
;
2610 if (tcgetattr(fd
, &old_termios
) < 0)
2613 struct termios new_termios
= old_termios
;
2614 termios_disable_echo(&new_termios
);
2616 if (tcsetattr(fd
, TCSANOW
, &new_termios
) < 0)
2619 r
= loop_write(fd
, DCS_TERMINFO_Q
, SIZE_MAX
);
2623 usec_t end
= usec_add(now(CLOCK_MONOTONIC
), CONSOLE_REPLY_WAIT_USEC
);
2624 char buf
[STRLEN(DCS_TERMINFO_R1
) + MAX_TERMINFO_LENGTH
+ STRLEN(ANSI_ST
)];
2628 usec_t n
= now(CLOCK_MONOTONIC
);
2634 r
= fd_wait_for_event(fd
, POLLIN
, usec_sub_unsigned(end
, n
));
2642 /* On the first read, read multiple characters, i.e. the shortest valid reply. Afterwards
2643 * read byte by byte, since we don't want to read too much and drop characters from the input
2645 ssize_t l
= read(fd
, buf
+ bytes
, bytes
== 0 ? STRLEN(DCS_TERMINFO_R0
) : 1);
2647 if (errno
== EAGAIN
)
2653 assert((size_t) l
<= sizeof(buf
) - bytes
);
2656 r
= scan_terminfo_response(buf
, bytes
, ret_name
);
2660 if (bytes
== sizeof(buf
)) {
2661 r
= -EOPNOTSUPP
; /* The response has the right prefix, but we didn't find a valid
2662 * answer with a terminator in the allotted space. Something is
2663 * wrong, possibly some unrelated bytes got injected into the
2670 (void) tcsetattr(fd
, TCSANOW
, &old_termios
);
2674 int have_terminfo_file(const char *name
) {
2675 /* This is a heuristic check if we have the file, using the directory layout used on
2676 * current Linux systems. Checks for other layouts can be added later if appropriate. */
2679 assert(filename_is_valid(name
));
2681 _cleanup_free_
char *p
= path_join("/usr/share/terminfo", CHAR_TO_STR(name
[0]), name
);
2683 return log_oom_debug();
2685 r
= RET_NERRNO(access(p
, F_OK
));
2693 int query_term_for_tty(const char *tty
, char **ret_term
) {
2694 _cleanup_free_
char *dcs_term
= NULL
;
2700 if (tty_is_vc_resolve(tty
))
2701 return strdup_to(ret_term
, "linux");
2703 /* Try to query the terminal implementation that we're on. This will not work in all
2704 * cases, which is fine, since this is intended to be used as a fallback. */
2706 _cleanup_close_
int tty_fd
= open_terminal(tty
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
|O_NONBLOCK
);
2708 return log_debug_errno(tty_fd
, "Failed to open %s to query terminfo: %m", tty
);
2710 r
= terminal_get_terminfo_by_dcs(tty_fd
, &dcs_term
);
2712 return log_debug_errno(r
, "Failed to query %s for terminfo: %m", tty
);
2714 r
= have_terminfo_file(dcs_term
);
2716 return log_debug_errno(r
, "Failed to look for terminfo %s: %m", dcs_term
);
2718 return log_info_errno(SYNTHETIC_ERRNO(ENODATA
),
2719 "Terminfo %s not found for %s.", dcs_term
, tty
);
2721 *ret_term
= TAKE_PTR(dcs_term
);
2725 int terminal_is_pty_fd(int fd
) {
2730 /* Returns true if we are looking at a pty, i.e. if it's backed by the /dev/pts/ file system */
2732 if (!isatty_safe(fd
))
2735 r
= is_fs_type_at(fd
, NULL
, DEVPTS_SUPER_MAGIC
);
2739 /* The ptmx device is weird, it exists twice, once inside and once outside devpts. To detect the
2740 * latter case, let's fire off an ioctl() that only works on ptmx devices. */
2743 if (ioctl(fd
, TIOCGPKT
, &v
) < 0) {
2744 if (ERRNO_IS_NOT_SUPPORTED(errno
))
2753 int pty_open_peer(int fd
, int mode
) {
2756 /* Opens the peer PTY using the new race-free TIOCGPTPEER ioctl() (kernel 4.13).
2758 * This is safe to be called on TTYs from other namespaces. */
2760 assert((mode
& (O_CREAT
|O_PATH
|O_DIRECTORY
|O_TMPFILE
)) == 0);
2762 /* This replicates the EIO retry logic of open_terminal() in a modified way. */
2763 for (unsigned c
= 0;; c
++) {
2764 int peer_fd
= ioctl(fd
, TIOCGPTPEER
, mode
);
2771 /* Max 1s in total */
2775 (void) usleep_safe(50 * USEC_PER_MSEC
);