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;
67 _cleanup_close_ int fd;
69 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
75 TIOCL_GETKMSGREDIRECT,
79 if (ioctl(fd, TIOCLINUX, tiocl) < 0)
82 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
85 if (ioctl(fd, VT_ACTIVATE, vt) < 0)
91 #if 0 /// UNNEEDED by elogind
92 int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
93 struct termios old_termios, new_termios;
94 char c, line[LINE_MAX];
99 if (tcgetattr(fileno(f), &old_termios) >= 0) {
100 new_termios = old_termios;
102 new_termios.c_lflag &= ~ICANON;
103 new_termios.c_cc[VMIN] = 1;
104 new_termios.c_cc[VTIME] = 0;
106 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
109 if (t != USEC_INFINITY) {
110 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
111 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
116 k = fread(&c, 1, 1, f);
118 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
124 *need_nl = c != '\n';
131 if (t != USEC_INFINITY) {
132 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
137 if (!fgets(line, sizeof(line), f))
138 return errno > 0 ? -errno : -EIO;
142 if (strlen(line) != 1)
152 #define DEFAULT_ASK_REFRESH_USEC (2*USEC_PER_SEC)
154 int ask_char(char *ret, const char *replies, const char *fmt, ...) {
166 if (colors_enabled())
167 fputs(ANSI_HIGHLIGHT, stdout);
175 if (colors_enabled())
176 fputs(ANSI_NORMAL, stdout);
180 r = read_one_char(stdin, &c, DEFAULT_ASK_REFRESH_USEC, &need_nl);
187 puts("Bad input, please try again.");
198 if (strchr(replies, c)) {
203 puts("Read unexpected character, please try again.");
207 int ask_string(char **ret, const char *text, ...) {
215 if (colors_enabled())
216 fputs(ANSI_HIGHLIGHT, stdout);
222 if (colors_enabled())
223 fputs(ANSI_NORMAL, stdout);
228 if (!fgets(line, sizeof(line), stdin))
229 return errno > 0 ? -errno : -EIO;
231 if (!endswith(line, "\n"))
250 int reset_terminal_fd(int fd, bool switch_to_text) {
251 struct termios termios;
254 /* Set terminal to some sane defaults */
258 /* We leave locked terminal attributes untouched, so that
259 * Plymouth may set whatever it wants to set, and we don't
260 * interfere with that. */
262 /* Disable exclusive mode, just in case */
263 (void) ioctl(fd, TIOCNXCL);
265 /* Switch to text mode */
267 (void) ioctl(fd, KDSETMODE, KD_TEXT);
269 /* Set default keyboard mode */
270 (void) vt_reset_keyboard(fd);
272 if (tcgetattr(fd, &termios) < 0) {
277 /* We only reset the stuff that matters to the software. How
278 * hardware is set up we don't touch assuming that somebody
279 * else will do that for us */
281 termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
282 termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
283 termios.c_oflag |= ONLCR;
284 termios.c_cflag |= CREAD;
285 termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
287 termios.c_cc[VINTR] = 03; /* ^C */
288 termios.c_cc[VQUIT] = 034; /* ^\ */
289 termios.c_cc[VERASE] = 0177;
290 termios.c_cc[VKILL] = 025; /* ^X */
291 termios.c_cc[VEOF] = 04; /* ^D */
292 termios.c_cc[VSTART] = 021; /* ^Q */
293 termios.c_cc[VSTOP] = 023; /* ^S */
294 termios.c_cc[VSUSP] = 032; /* ^Z */
295 termios.c_cc[VLNEXT] = 026; /* ^V */
296 termios.c_cc[VWERASE] = 027; /* ^W */
297 termios.c_cc[VREPRINT] = 022; /* ^R */
298 termios.c_cc[VEOL] = 0;
299 termios.c_cc[VEOL2] = 0;
301 termios.c_cc[VTIME] = 0;
302 termios.c_cc[VMIN] = 1;
304 if (tcsetattr(fd, TCSANOW, &termios) < 0)
308 /* Just in case, flush all crap out */
309 (void) tcflush(fd, TCIOFLUSH);
314 int reset_terminal(const char *name) {
315 _cleanup_close_ int fd = -1;
317 /* We open the terminal with O_NONBLOCK here, to ensure we
318 * don't block on carrier if this is a terminal with carrier
321 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
325 return reset_terminal_fd(fd, true);
329 int open_terminal(const char *name, int mode) {
334 * If a TTY is in the process of being closed opening it might
335 * cause EIO. This is horribly awful, but unlikely to be
336 * changed in the kernel. Hence we work around this problem by
337 * retrying a couple of times.
339 * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
346 fd = open(name, mode, 0);
353 /* Max 1s in total */
357 usleep(50 * USEC_PER_MSEC);
370 #if 0 /// UNNEEDED by elogind
371 int acquire_terminal(
373 AcquireTerminalFlags flags,
376 _cleanup_close_ int notify = -1, fd = -1;
377 usec_t ts = USEC_INFINITY;
381 assert(IN_SET(flags & ~ACQUIRE_TERMINAL_PERMISSIVE, ACQUIRE_TERMINAL_TRY, ACQUIRE_TERMINAL_FORCE, ACQUIRE_TERMINAL_WAIT));
383 /* We use inotify to be notified when the tty is closed. We create the watch before checking if we can actually
384 * acquire it, so that we don't lose any event.
386 * Note: strictly speaking this actually watches for the device being closed, it does *not* really watch
387 * whether a tty loses its controlling process. However, unless some rogue process uses TIOCNOTTY on /dev/tty
388 * *after* closing its tty otherwise this will not become a problem. As long as the administrator makes sure
389 * not configure any service on the same tty as an untrusted user this should not be a problem. (Which he
390 * probably should not do anyway.) */
392 if ((flags & ~ACQUIRE_TERMINAL_PERMISSIVE) == ACQUIRE_TERMINAL_WAIT) {
393 notify = inotify_init1(IN_CLOEXEC | (timeout != USEC_INFINITY ? IN_NONBLOCK : 0));
397 wd = inotify_add_watch(notify, name, IN_CLOSE);
401 if (timeout != USEC_INFINITY)
402 ts = now(CLOCK_MONOTONIC);
406 struct sigaction sa_old, sa_new = {
407 .sa_handler = SIG_IGN,
408 .sa_flags = SA_RESTART,
412 r = flush_fd(notify);
417 /* We pass here O_NOCTTY only so that we can check the return value TIOCSCTTY and have a reliable way
418 * to figure out if we successfully became the controlling process of the tty */
419 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
423 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed if we already own the tty. */
424 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
426 /* First, try to get the tty */
427 r = ioctl(fd, TIOCSCTTY,
428 (flags & ~ACQUIRE_TERMINAL_PERMISSIVE) == ACQUIRE_TERMINAL_FORCE) < 0 ? -errno : 0;
430 /* Reset signal handler to old value */
431 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
433 /* Success? Exit the loop now! */
437 /* Any failure besides -EPERM? Fail, regardless of the mode. */
441 if (flags & ACQUIRE_TERMINAL_PERMISSIVE) /* If we are in permissive mode, then EPERM is fine, turn this
442 * into a success. Note that EPERM is also returned if we
443 * already are the owner of the TTY. */
446 if (flags != ACQUIRE_TERMINAL_WAIT) /* If we are in TRY or FORCE mode, then propagate EPERM as EPERM */
453 union inotify_event_buffer buffer;
454 struct inotify_event *e;
457 if (timeout != USEC_INFINITY) {
460 assert(ts != USEC_INFINITY);
462 n = now(CLOCK_MONOTONIC);
463 if (ts + timeout < n)
466 r = fd_wait_for_event(notify, POLLIN, ts + timeout - n);
473 l = read(notify, &buffer, sizeof(buffer));
475 if (IN_SET(errno, EINTR, EAGAIN))
481 FOREACH_INOTIFY_EVENT(e, buffer, l) {
482 if (e->mask & IN_Q_OVERFLOW) /* If we hit an inotify queue overflow, simply check if the terminal is up for grabs now. */
485 if (e->wd != wd || !(e->mask & IN_CLOSE)) /* Safety checks */
492 /* We close the tty fd here since if the old session ended our handle will be dead. It's important that
493 * we do this after sleeping, so that we don't enter an endless loop. */
504 #if 0 /// UNNEEDED by elogind
505 int release_terminal(void) {
506 static const struct sigaction sa_new = {
507 .sa_handler = SIG_IGN,
508 .sa_flags = SA_RESTART,
511 _cleanup_close_ int fd = -1;
512 struct sigaction sa_old;
515 fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
519 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
520 * by our own TIOCNOTTY */
521 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
523 if (ioctl(fd, TIOCNOTTY) < 0)
526 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
531 int terminal_vhangup_fd(int fd) {
534 if (ioctl(fd, TIOCVHANGUP) < 0)
540 int terminal_vhangup(const char *name) {
541 _cleanup_close_ int fd;
543 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
547 return terminal_vhangup_fd(fd);
550 int vt_disallocate(const char *name) {
551 _cleanup_close_ int fd = -1;
556 /* Deallocate the VT if possible. If not possible
557 * (i.e. because it is the active one), at least clear it
558 * entirely (including the scrollback buffer) */
560 e = path_startswith(name, "/dev/");
564 if (!tty_is_vc(name)) {
565 /* So this is not a VT. I guess we cannot deallocate
566 * it then. But let's at least clear the screen */
568 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
573 "\033[r" /* clear scrolling region */
574 "\033[H" /* move home */
575 "\033[2J", /* clear screen */
580 n = startswith(e, "tty");
584 r = safe_atou(n, &u);
591 /* Try to deallocate */
592 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
596 r = ioctl(fd, VT_DISALLOCATE, u);
605 /* Couldn't deallocate, so let's clear it fully with
607 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
612 "\033[r" /* clear scrolling region */
613 "\033[H" /* move home */
614 "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
619 int make_console_stdio(void) {
622 /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
624 fd = acquire_terminal("/dev/console", ACQUIRE_TERMINAL_FORCE|ACQUIRE_TERMINAL_PERMISSIVE, USEC_INFINITY);
626 return log_error_errno(fd, "Failed to acquire terminal: %m");
628 r = reset_terminal_fd(fd, true);
630 log_warning_errno(r, "Failed to reset terminal, ignoring: %m");
634 return log_error_errno(r, "Failed to duplicate terminal fd: %m");
640 bool tty_is_vc(const char *tty) {
643 return vtnr_from_tty(tty) >= 0;
646 bool tty_is_console(const char *tty) {
649 return streq(skip_dev_prefix(tty), "console");
652 int vtnr_from_tty(const char *tty) {
657 tty = skip_dev_prefix(tty);
659 if (!startswith(tty, "tty") )
662 if (tty[3] < '0' || tty[3] > '9')
665 r = safe_atoi(tty+3, &i);
675 #if 0 /// UNNEEDED by elogind
676 char *resolve_dev_console(char **active) {
679 /* Resolve where /dev/console is pointing to, if /sys is actually ours
680 * (i.e. not read-only-mounted which is a sign for container setups) */
682 if (path_is_read_only_fs("/sys") > 0)
685 if (read_one_line_file("/sys/class/tty/console/active", active) < 0)
688 /* If multiple log outputs are configured the last one is what
689 * /dev/console points to */
690 tty = strrchr(*active, ' ');
696 if (streq(tty, "tty0")) {
699 /* Get the active VC (e.g. tty1) */
700 if (read_one_line_file("/sys/class/tty/tty0/active", &tmp) >= 0) {
709 int get_kernel_consoles(char ***consoles) {
710 _cleanup_strv_free_ char **con = NULL;
711 _cleanup_free_ char *line = NULL;
717 r = read_one_line_file("/sys/class/tty/console/active", &line);
723 _cleanup_free_ char *tty = NULL;
726 r = extract_first_word(&active, &tty, NULL, 0);
732 if (streq(tty, "tty0")) {
734 r = read_one_line_file("/sys/class/tty/tty0/active", &tty);
739 path = strappend("/dev/", tty);
743 if (access(path, F_OK) < 0) {
744 log_debug_errno(errno, "Console device %s is not accessible, skipping: %m", path);
749 r = strv_consume(&con, path);
754 if (strv_isempty(con)) {
755 log_debug("No devices found for system console");
757 r = strv_extend(&con, "/dev/console");
767 bool tty_is_vc_resolve(const char *tty) {
768 _cleanup_free_ char *active = NULL;
772 tty = skip_dev_prefix(tty);
774 if (streq(tty, "console")) {
775 tty = resolve_dev_console(&active);
780 return tty_is_vc(tty);
783 const char *default_term_for_tty(const char *tty) {
784 return tty && tty_is_vc_resolve(tty) ? "linux" : "vt220";
788 int fd_columns(int fd) {
789 struct winsize ws = {};
791 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
800 unsigned columns(void) {
804 if (_likely_(cached_columns > 0))
805 return cached_columns;
808 e = getenv("COLUMNS");
810 (void) safe_atoi(e, &c);
813 c = fd_columns(STDOUT_FILENO);
819 return cached_columns;
822 int fd_lines(int fd) {
823 struct winsize ws = {};
825 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
834 unsigned lines(void) {
838 if (_likely_(cached_lines > 0))
844 (void) safe_atoi(e, &l);
847 l = fd_lines(STDOUT_FILENO);
856 /* intended to be used as a SIGWINCH sighandler */
857 #if 0 /// UNNEEDED by elogind
858 void columns_lines_cache_reset(int signum) {
865 static int cached_on_tty = -1;
867 if (_unlikely_(cached_on_tty < 0))
868 cached_on_tty = isatty(STDOUT_FILENO) > 0;
870 return cached_on_tty;
873 int make_stdio(int fd) {
878 if (dup2(fd, STDIN_FILENO) < 0 && r >= 0)
880 if (dup2(fd, STDOUT_FILENO) < 0 && r >= 0)
882 if (dup2(fd, STDERR_FILENO) < 0 && r >= 0)
888 /* Explicitly unset O_CLOEXEC, since if fd was < 3, then dup2() was a NOP and the bit hence possibly set. */
889 stdio_unset_cloexec();
894 int make_null_stdio(void) {
897 null_fd = open("/dev/null", O_RDWR|O_NOCTTY|O_CLOEXEC);
901 return make_stdio(null_fd);
904 int getttyname_malloc(int fd, char **ret) {
914 r = ttyname_r(fd, path, sizeof(path));
918 c = strdup(skip_dev_prefix(path));
935 int getttyname_harder(int fd, char **r) {
939 k = getttyname_malloc(fd, &s);
943 if (streq(s, "tty")) {
945 return get_ctty(0, NULL, r);
952 int get_ctty_devnr(pid_t pid, dev_t *d) {
954 _cleanup_free_ char *line = NULL;
960 p = procfs_file_alloca(pid, "stat");
961 r = read_one_line_file(p, &line);
965 p = strrchr(line, ')');
980 if (major(ttynr) == 0 && minor(ttynr) == 0)
989 int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
990 char fn[STRLEN("/dev/char/") + 2*DECIMAL_STR_MAX(unsigned) + 1 + 1], *b = NULL;
991 _cleanup_free_ char *s = NULL;
998 k = get_ctty_devnr(pid, &devnr);
1002 sprintf(fn, "/dev/char/%u:%u", major(devnr), minor(devnr));
1004 k = readlink_malloc(fn, &s);
1010 /* This is an ugly hack */
1011 if (major(devnr) == 136) {
1012 if (asprintf(&b, "pts/%u", minor(devnr)) < 0)
1015 /* Probably something like the ptys which have no
1016 * symlink in /dev/char. Let's return something
1017 * vaguely useful. */
1024 if (startswith(s, "/dev/"))
1026 else if (startswith(s, "../"))
1043 #if 0 /// UNNEEDED by elogind
1044 int ptsname_malloc(int fd, char **ret) {
1057 if (ptsname_r(fd, c, l) == 0) {
1061 if (errno != ERANGE) {
1071 int ptsname_namespace(int pty, char **ret) {
1074 /* Like ptsname(), but doesn't assume that the path is
1075 * accessible in the local namespace. */
1077 r = ioctl(pty, TIOCGPTN, &no);
1084 if (asprintf(ret, "/dev/pts/%i", no) < 0)
1090 int openpt_in_namespace(pid_t pid, int flags) {
1091 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1;
1092 _cleanup_close_pair_ int pair[2] = { -1, -1 };
1098 r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &usernsfd, &rootfd);
1102 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
1105 r = safe_fork("(sd-openpt)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &child);
1111 pair[0] = safe_close(pair[0]);
1113 r = namespace_enter(pidnsfd, mntnsfd, -1, usernsfd, rootfd);
1115 _exit(EXIT_FAILURE);
1117 master = posix_openpt(flags|O_NOCTTY|O_CLOEXEC);
1119 _exit(EXIT_FAILURE);
1121 if (unlockpt(master) < 0)
1122 _exit(EXIT_FAILURE);
1124 if (send_one_fd(pair[1], master, 0) < 0)
1125 _exit(EXIT_FAILURE);
1127 _exit(EXIT_SUCCESS);
1130 pair[1] = safe_close(pair[1]);
1132 r = wait_for_terminate_and_check("(sd-openpt)", child, 0);
1135 if (r != EXIT_SUCCESS)
1138 return receive_one_fd(pair[0], 0);
1141 int open_terminal_in_namespace(pid_t pid, const char *name, int mode) {
1142 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1;
1143 _cleanup_close_pair_ int pair[2] = { -1, -1 };
1147 r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &usernsfd, &rootfd);
1151 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
1154 r = safe_fork("(sd-terminal)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &child);
1160 pair[0] = safe_close(pair[0]);
1162 r = namespace_enter(pidnsfd, mntnsfd, -1, usernsfd, rootfd);
1164 _exit(EXIT_FAILURE);
1166 master = open_terminal(name, mode|O_NOCTTY|O_CLOEXEC);
1168 _exit(EXIT_FAILURE);
1170 if (send_one_fd(pair[1], master, 0) < 0)
1171 _exit(EXIT_FAILURE);
1173 _exit(EXIT_SUCCESS);
1176 pair[1] = safe_close(pair[1]);
1178 r = wait_for_terminate_and_check("(sd-terminal)", child, 0);
1181 if (r != EXIT_SUCCESS)
1184 return receive_one_fd(pair[0], 0);
1188 static bool getenv_terminal_is_dumb(void) {
1195 return streq(e, "dumb");
1198 bool terminal_is_dumb(void) {
1202 return getenv_terminal_is_dumb();
1205 bool colors_enabled(void) {
1206 static int enabled = -1;
1208 if (_unlikely_(enabled < 0)) {
1209 #if 0 /// elogind does not allow such forcing, and we are never init!
1212 val = getenv_bool("SYSTEMD_COLORS");
1215 else if (getpid_cached() == 1)
1216 /* PID1 outputs to the console without holding it open all the time */
1217 enabled = !getenv_terminal_is_dumb();
1220 enabled = !terminal_is_dumb();
1226 bool underline_enabled(void) {
1227 static int enabled = -1;
1231 /* The Linux console doesn't support underlining, turn it off, but only there. */
1233 if (!colors_enabled())
1236 enabled = !streq_ptr(getenv("TERM"), "linux");
1242 int vt_default_utf8(void) {
1243 _cleanup_free_ char *b = NULL;
1246 /* Read the default VT UTF8 setting from the kernel */
1248 r = read_one_line_file("/sys/module/vt/parameters/default_utf8", &b);
1252 return parse_boolean(b);
1255 int vt_reset_keyboard(int fd) {
1258 /* If we can't read the default, then default to unicode. It's 2017 after all. */
1259 kb = vt_default_utf8() != 0 ? K_UNICODE : K_XLATE;
1261 if (ioctl(fd, KDSKBMODE, kb) < 0)