1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
28 #include <sys/inotify.h>
29 #include <sys/socket.h>
30 #include <sys/sysmacros.h>
33 #include <linux/tiocl.h>
37 #include <sys/ioctl.h>
38 #include <sys/types.h>
42 #include "alloc-util.h"
50 #include "parse-util.h"
51 #include "process-util.h"
52 #include "socket-util.h"
53 #include "stat-util.h"
54 #include "string-util.h"
56 #include "terminal-util.h"
57 #include "time-util.h"
60 /// Additional includes needed by elogind
61 #include "path-util.h"
63 static volatile unsigned cached_columns = 0;
64 static volatile unsigned cached_lines = 0;
66 static volatile int cached_on_tty = -1;
67 static volatile int cached_colors_enabled = -1;
68 static volatile int cached_underline_enabled = -1;
71 _cleanup_close_ int fd;
73 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
79 TIOCL_GETKMSGREDIRECT,
83 if (ioctl(fd, TIOCLINUX, tiocl) < 0)
86 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
89 if (ioctl(fd, VT_ACTIVATE, vt) < 0)
95 #if 0 /// UNNEEDED by elogind
96 int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
97 struct termios old_termios, new_termios;
98 char c, line[LINE_MAX];
103 if (tcgetattr(fileno(f), &old_termios) >= 0) {
104 new_termios = old_termios;
106 new_termios.c_lflag &= ~ICANON;
107 new_termios.c_cc[VMIN] = 1;
108 new_termios.c_cc[VTIME] = 0;
110 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
113 if (t != USEC_INFINITY) {
114 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
115 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
120 k = fread(&c, 1, 1, f);
122 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
128 *need_nl = c != '\n';
135 if (t != USEC_INFINITY) {
136 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
141 if (!fgets(line, sizeof(line), f))
142 return errno > 0 ? -errno : -EIO;
146 if (strlen(line) != 1)
156 #define DEFAULT_ASK_REFRESH_USEC (2*USEC_PER_SEC)
158 int ask_char(char *ret, const char *replies, const char *fmt, ...) {
170 if (colors_enabled())
171 fputs(ANSI_HIGHLIGHT, stdout);
179 if (colors_enabled())
180 fputs(ANSI_NORMAL, stdout);
184 r = read_one_char(stdin, &c, DEFAULT_ASK_REFRESH_USEC, &need_nl);
191 puts("Bad input, please try again.");
202 if (strchr(replies, c)) {
207 puts("Read unexpected character, please try again.");
211 int ask_string(char **ret, const char *text, ...) {
219 if (colors_enabled())
220 fputs(ANSI_HIGHLIGHT, stdout);
226 if (colors_enabled())
227 fputs(ANSI_NORMAL, stdout);
232 if (!fgets(line, sizeof(line), stdin))
233 return errno > 0 ? -errno : -EIO;
235 if (!endswith(line, "\n"))
254 int reset_terminal_fd(int fd, bool switch_to_text) {
255 struct termios termios;
258 /* Set terminal to some sane defaults */
262 /* We leave locked terminal attributes untouched, so that
263 * Plymouth may set whatever it wants to set, and we don't
264 * interfere with that. */
266 /* Disable exclusive mode, just in case */
267 (void) ioctl(fd, TIOCNXCL);
269 /* Switch to text mode */
271 (void) ioctl(fd, KDSETMODE, KD_TEXT);
273 /* Set default keyboard mode */
274 (void) vt_reset_keyboard(fd);
276 if (tcgetattr(fd, &termios) < 0) {
281 /* We only reset the stuff that matters to the software. How
282 * hardware is set up we don't touch assuming that somebody
283 * else will do that for us */
285 termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
286 termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
287 termios.c_oflag |= ONLCR;
288 termios.c_cflag |= CREAD;
289 termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
291 termios.c_cc[VINTR] = 03; /* ^C */
292 termios.c_cc[VQUIT] = 034; /* ^\ */
293 termios.c_cc[VERASE] = 0177;
294 termios.c_cc[VKILL] = 025; /* ^X */
295 termios.c_cc[VEOF] = 04; /* ^D */
296 termios.c_cc[VSTART] = 021; /* ^Q */
297 termios.c_cc[VSTOP] = 023; /* ^S */
298 termios.c_cc[VSUSP] = 032; /* ^Z */
299 termios.c_cc[VLNEXT] = 026; /* ^V */
300 termios.c_cc[VWERASE] = 027; /* ^W */
301 termios.c_cc[VREPRINT] = 022; /* ^R */
302 termios.c_cc[VEOL] = 0;
303 termios.c_cc[VEOL2] = 0;
305 termios.c_cc[VTIME] = 0;
306 termios.c_cc[VMIN] = 1;
308 if (tcsetattr(fd, TCSANOW, &termios) < 0)
312 /* Just in case, flush all crap out */
313 (void) tcflush(fd, TCIOFLUSH);
318 int reset_terminal(const char *name) {
319 _cleanup_close_ int fd = -1;
321 /* We open the terminal with O_NONBLOCK here, to ensure we
322 * don't block on carrier if this is a terminal with carrier
325 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
329 return reset_terminal_fd(fd, true);
333 int open_terminal(const char *name, int mode) {
338 * If a TTY is in the process of being closed opening it might
339 * cause EIO. This is horribly awful, but unlikely to be
340 * changed in the kernel. Hence we work around this problem by
341 * retrying a couple of times.
343 * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
350 fd = open(name, mode, 0);
357 /* Max 1s in total */
361 usleep(50 * USEC_PER_MSEC);
374 #if 0 /// UNNEEDED by elogind
375 int acquire_terminal(
377 AcquireTerminalFlags flags,
380 _cleanup_close_ int notify = -1, fd = -1;
381 usec_t ts = USEC_INFINITY;
385 assert(IN_SET(flags & ~ACQUIRE_TERMINAL_PERMISSIVE, ACQUIRE_TERMINAL_TRY, ACQUIRE_TERMINAL_FORCE, ACQUIRE_TERMINAL_WAIT));
387 /* We use inotify to be notified when the tty is closed. We create the watch before checking if we can actually
388 * acquire it, so that we don't lose any event.
390 * Note: strictly speaking this actually watches for the device being closed, it does *not* really watch
391 * whether a tty loses its controlling process. However, unless some rogue process uses TIOCNOTTY on /dev/tty
392 * *after* closing its tty otherwise this will not become a problem. As long as the administrator makes sure
393 * not configure any service on the same tty as an untrusted user this should not be a problem. (Which he
394 * probably should not do anyway.) */
396 if ((flags & ~ACQUIRE_TERMINAL_PERMISSIVE) == ACQUIRE_TERMINAL_WAIT) {
397 notify = inotify_init1(IN_CLOEXEC | (timeout != USEC_INFINITY ? IN_NONBLOCK : 0));
401 wd = inotify_add_watch(notify, name, IN_CLOSE);
405 if (timeout != USEC_INFINITY)
406 ts = now(CLOCK_MONOTONIC);
410 struct sigaction sa_old, sa_new = {
411 .sa_handler = SIG_IGN,
412 .sa_flags = SA_RESTART,
416 r = flush_fd(notify);
421 /* We pass here O_NOCTTY only so that we can check the return value TIOCSCTTY and have a reliable way
422 * to figure out if we successfully became the controlling process of the tty */
423 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
427 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed if we already own the tty. */
428 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
430 /* First, try to get the tty */
431 r = ioctl(fd, TIOCSCTTY,
432 (flags & ~ACQUIRE_TERMINAL_PERMISSIVE) == ACQUIRE_TERMINAL_FORCE) < 0 ? -errno : 0;
434 /* Reset signal handler to old value */
435 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
437 /* Success? Exit the loop now! */
441 /* Any failure besides -EPERM? Fail, regardless of the mode. */
445 if (flags & ACQUIRE_TERMINAL_PERMISSIVE) /* If we are in permissive mode, then EPERM is fine, turn this
446 * into a success. Note that EPERM is also returned if we
447 * already are the owner of the TTY. */
450 if (flags != ACQUIRE_TERMINAL_WAIT) /* If we are in TRY or FORCE mode, then propagate EPERM as EPERM */
457 union inotify_event_buffer buffer;
458 struct inotify_event *e;
461 if (timeout != USEC_INFINITY) {
464 assert(ts != USEC_INFINITY);
466 n = now(CLOCK_MONOTONIC);
467 if (ts + timeout < n)
470 r = fd_wait_for_event(notify, POLLIN, ts + timeout - n);
477 l = read(notify, &buffer, sizeof(buffer));
479 if (IN_SET(errno, EINTR, EAGAIN))
485 FOREACH_INOTIFY_EVENT(e, buffer, l) {
486 if (e->mask & IN_Q_OVERFLOW) /* If we hit an inotify queue overflow, simply check if the terminal is up for grabs now. */
489 if (e->wd != wd || !(e->mask & IN_CLOSE)) /* Safety checks */
496 /* We close the tty fd here since if the old session ended our handle will be dead. It's important that
497 * we do this after sleeping, so that we don't enter an endless loop. */
508 #if 0 /// UNNEEDED by elogind
509 int release_terminal(void) {
510 static const struct sigaction sa_new = {
511 .sa_handler = SIG_IGN,
512 .sa_flags = SA_RESTART,
515 _cleanup_close_ int fd = -1;
516 struct sigaction sa_old;
519 fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
523 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
524 * by our own TIOCNOTTY */
525 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
527 if (ioctl(fd, TIOCNOTTY) < 0)
530 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
535 int terminal_vhangup_fd(int fd) {
538 if (ioctl(fd, TIOCVHANGUP) < 0)
544 int terminal_vhangup(const char *name) {
545 _cleanup_close_ int fd;
547 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
551 return terminal_vhangup_fd(fd);
554 int vt_disallocate(const char *name) {
555 _cleanup_close_ int fd = -1;
560 /* Deallocate the VT if possible. If not possible
561 * (i.e. because it is the active one), at least clear it
562 * entirely (including the scrollback buffer) */
564 e = path_startswith(name, "/dev/");
568 if (!tty_is_vc(name)) {
569 /* So this is not a VT. I guess we cannot deallocate
570 * it then. But let's at least clear the screen */
572 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
577 "\033[r" /* clear scrolling region */
578 "\033[H" /* move home */
579 "\033[2J", /* clear screen */
584 n = startswith(e, "tty");
588 r = safe_atou(n, &u);
595 /* Try to deallocate */
596 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
600 r = ioctl(fd, VT_DISALLOCATE, u);
609 /* Couldn't deallocate, so let's clear it fully with
611 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
616 "\033[r" /* clear scrolling region */
617 "\033[H" /* move home */
618 "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
623 int make_console_stdio(void) {
626 /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
628 fd = acquire_terminal("/dev/console", ACQUIRE_TERMINAL_FORCE|ACQUIRE_TERMINAL_PERMISSIVE, USEC_INFINITY);
630 return log_error_errno(fd, "Failed to acquire terminal: %m");
632 r = reset_terminal_fd(fd, true);
634 log_warning_errno(r, "Failed to reset terminal, ignoring: %m");
638 return log_error_errno(r, "Failed to duplicate terminal fd: %m");
640 reset_terminal_feature_caches();
646 bool tty_is_vc(const char *tty) {
649 return vtnr_from_tty(tty) >= 0;
652 bool tty_is_console(const char *tty) {
655 return streq(skip_dev_prefix(tty), "console");
658 int vtnr_from_tty(const char *tty) {
663 tty = skip_dev_prefix(tty);
665 if (!startswith(tty, "tty") )
668 if (tty[3] < '0' || tty[3] > '9')
671 r = safe_atoi(tty+3, &i);
681 #if 0 /// UNNEEDED by elogind
682 char *resolve_dev_console(char **active) {
685 /* Resolve where /dev/console is pointing to, if /sys is actually ours
686 * (i.e. not read-only-mounted which is a sign for container setups) */
688 if (path_is_read_only_fs("/sys") > 0)
691 if (read_one_line_file("/sys/class/tty/console/active", active) < 0)
694 /* If multiple log outputs are configured the last one is what
695 * /dev/console points to */
696 tty = strrchr(*active, ' ');
702 if (streq(tty, "tty0")) {
705 /* Get the active VC (e.g. tty1) */
706 if (read_one_line_file("/sys/class/tty/tty0/active", &tmp) >= 0) {
715 int get_kernel_consoles(char ***consoles) {
716 _cleanup_strv_free_ char **con = NULL;
717 _cleanup_free_ char *line = NULL;
723 r = read_one_line_file("/sys/class/tty/console/active", &line);
729 _cleanup_free_ char *tty = NULL;
732 r = extract_first_word(&active, &tty, NULL, 0);
738 if (streq(tty, "tty0")) {
740 r = read_one_line_file("/sys/class/tty/tty0/active", &tty);
745 path = strappend("/dev/", tty);
749 if (access(path, F_OK) < 0) {
750 log_debug_errno(errno, "Console device %s is not accessible, skipping: %m", path);
755 r = strv_consume(&con, path);
760 if (strv_isempty(con)) {
761 log_debug("No devices found for system console");
763 r = strv_extend(&con, "/dev/console");
773 bool tty_is_vc_resolve(const char *tty) {
774 _cleanup_free_ char *active = NULL;
778 tty = skip_dev_prefix(tty);
780 if (streq(tty, "console")) {
781 tty = resolve_dev_console(&active);
786 return tty_is_vc(tty);
789 const char *default_term_for_tty(const char *tty) {
790 return tty && tty_is_vc_resolve(tty) ? "linux" : "vt220";
794 int fd_columns(int fd) {
795 struct winsize ws = {};
797 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
806 unsigned columns(void) {
810 if (cached_columns > 0)
811 return cached_columns;
814 e = getenv("COLUMNS");
816 (void) safe_atoi(e, &c);
819 c = fd_columns(STDOUT_FILENO);
825 return cached_columns;
828 int fd_lines(int fd) {
829 struct winsize ws = {};
831 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
840 unsigned lines(void) {
844 if (cached_lines > 0)
850 (void) safe_atoi(e, &l);
853 l = fd_lines(STDOUT_FILENO);
862 /* intended to be used as a SIGWINCH sighandler */
863 #if 0 /// UNNEEDED by elogind
864 void columns_lines_cache_reset(int signum) {
870 void reset_terminal_feature_caches(void) {
874 cached_colors_enabled = -1;
875 cached_underline_enabled = -1;
880 if (cached_on_tty < 0)
881 cached_on_tty = isatty(STDOUT_FILENO) > 0;
883 return cached_on_tty;
886 int make_stdio(int fd) {
891 if (dup2(fd, STDIN_FILENO) < 0)
893 if (dup2(fd, STDOUT_FILENO) < 0 && r >= 0)
895 if (dup2(fd, STDERR_FILENO) < 0 && r >= 0)
901 /* Explicitly unset O_CLOEXEC, since if fd was < 3, then dup2() was a NOP and the bit hence possibly set. */
902 stdio_unset_cloexec();
907 int make_null_stdio(void) {
910 null_fd = open("/dev/null", O_RDWR|O_NOCTTY|O_CLOEXEC);
914 r = make_stdio(null_fd);
916 reset_terminal_feature_caches();
921 int getttyname_malloc(int fd, char **ret) {
931 r = ttyname_r(fd, path, sizeof(path));
935 c = strdup(skip_dev_prefix(path));
952 int getttyname_harder(int fd, char **r) {
956 k = getttyname_malloc(fd, &s);
960 if (streq(s, "tty")) {
962 return get_ctty(0, NULL, r);
969 int get_ctty_devnr(pid_t pid, dev_t *d) {
971 _cleanup_free_ char *line = NULL;
977 p = procfs_file_alloca(pid, "stat");
978 r = read_one_line_file(p, &line);
982 p = strrchr(line, ')');
997 if (major(ttynr) == 0 && minor(ttynr) == 0)
1006 int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
1007 char fn[STRLEN("/dev/char/") + 2*DECIMAL_STR_MAX(unsigned) + 1 + 1], *b = NULL;
1008 _cleanup_free_ char *s = NULL;
1015 k = get_ctty_devnr(pid, &devnr);
1019 sprintf(fn, "/dev/char/%u:%u", major(devnr), minor(devnr));
1021 k = readlink_malloc(fn, &s);
1027 /* This is an ugly hack */
1028 if (major(devnr) == 136) {
1029 if (asprintf(&b, "pts/%u", minor(devnr)) < 0)
1032 /* Probably something like the ptys which have no
1033 * symlink in /dev/char. Let's return something
1034 * vaguely useful. */
1041 if (startswith(s, "/dev/"))
1043 else if (startswith(s, "../"))
1060 #if 0 /// UNNEEDED by elogind
1061 int ptsname_malloc(int fd, char **ret) {
1074 if (ptsname_r(fd, c, l) == 0) {
1078 if (errno != ERANGE) {
1088 int ptsname_namespace(int pty, char **ret) {
1091 /* Like ptsname(), but doesn't assume that the path is
1092 * accessible in the local namespace. */
1094 r = ioctl(pty, TIOCGPTN, &no);
1101 if (asprintf(ret, "/dev/pts/%i", no) < 0)
1107 int openpt_in_namespace(pid_t pid, int flags) {
1108 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1;
1109 _cleanup_close_pair_ int pair[2] = { -1, -1 };
1115 r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &usernsfd, &rootfd);
1119 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
1122 r = safe_fork("(sd-openpt)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &child);
1128 pair[0] = safe_close(pair[0]);
1130 r = namespace_enter(pidnsfd, mntnsfd, -1, usernsfd, rootfd);
1132 _exit(EXIT_FAILURE);
1134 master = posix_openpt(flags|O_NOCTTY|O_CLOEXEC);
1136 _exit(EXIT_FAILURE);
1138 if (unlockpt(master) < 0)
1139 _exit(EXIT_FAILURE);
1141 if (send_one_fd(pair[1], master, 0) < 0)
1142 _exit(EXIT_FAILURE);
1144 _exit(EXIT_SUCCESS);
1147 pair[1] = safe_close(pair[1]);
1149 r = wait_for_terminate_and_check("(sd-openpt)", child, 0);
1152 if (r != EXIT_SUCCESS)
1155 return receive_one_fd(pair[0], 0);
1158 int open_terminal_in_namespace(pid_t pid, const char *name, int mode) {
1159 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1;
1160 _cleanup_close_pair_ int pair[2] = { -1, -1 };
1164 r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &usernsfd, &rootfd);
1168 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
1171 r = safe_fork("(sd-terminal)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &child);
1177 pair[0] = safe_close(pair[0]);
1179 r = namespace_enter(pidnsfd, mntnsfd, -1, usernsfd, rootfd);
1181 _exit(EXIT_FAILURE);
1183 master = open_terminal(name, mode|O_NOCTTY|O_CLOEXEC);
1185 _exit(EXIT_FAILURE);
1187 if (send_one_fd(pair[1], master, 0) < 0)
1188 _exit(EXIT_FAILURE);
1190 _exit(EXIT_SUCCESS);
1193 pair[1] = safe_close(pair[1]);
1195 r = wait_for_terminate_and_check("(sd-terminal)", child, 0);
1198 if (r != EXIT_SUCCESS)
1201 return receive_one_fd(pair[0], 0);
1205 static bool getenv_terminal_is_dumb(void) {
1212 return streq(e, "dumb");
1215 bool terminal_is_dumb(void) {
1219 return getenv_terminal_is_dumb();
1222 bool colors_enabled(void) {
1224 if (cached_colors_enabled < 0) {
1225 #if 0 /// elogind does not allow such forcing, and we are never init!
1228 val = getenv_bool("SYSTEMD_COLORS");
1230 cached_colors_enabled = val;
1231 else if (getpid_cached() == 1)
1232 /* PID1 outputs to the console without holding it open all the time */
1233 cached_colors_enabled = !getenv_terminal_is_dumb();
1236 cached_colors_enabled = !terminal_is_dumb();
1239 return cached_colors_enabled;
1242 bool underline_enabled(void) {
1244 if (cached_underline_enabled < 0) {
1246 /* The Linux console doesn't support underlining, turn it off, but only there. */
1248 if (colors_enabled())
1249 cached_underline_enabled = !streq_ptr(getenv("TERM"), "linux");
1251 cached_underline_enabled = false;
1254 return cached_underline_enabled;
1257 int vt_default_utf8(void) {
1258 _cleanup_free_ char *b = NULL;
1261 /* Read the default VT UTF8 setting from the kernel */
1263 r = read_one_line_file("/sys/module/vt/parameters/default_utf8", &b);
1267 return parse_boolean(b);
1270 int vt_reset_keyboard(int fd) {
1273 /* If we can't read the default, then default to unicode. It's 2017 after all. */
1274 kb = vt_default_utf8() != 0 ? K_UNICODE : K_XLATE;
1276 if (ioctl(fd, KDSKBMODE, kb) < 0)