From: Lennart Poettering Date: Thu, 11 Jul 2024 15:45:34 +0000 (+0200) Subject: terminal-util: refactor vt_disallocate() X-Git-Tag: v257-rc1~873^2~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=45d785dfc03f5b7ec62faf69e6d7ff18c807b93d;p=thirdparty%2Fsystemd.git terminal-util: refactor vt_disallocate() Numerous fixes: 1. use vtnr_from_tty() to parse out VT number from tty path 2. open tty for write only when we want to output just ansi sequences 3. open tty in asynchronous mode, and apply a timeout, just to be safe 4. propagate error from writing (most callers ignore it anyway, might as well pass it along correctly) --- diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index 4c9816d9698..d8253037ec4 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -433,60 +433,39 @@ int terminal_vhangup_fd(int fd) { return RET_NERRNO(ioctl(fd, TIOCVHANGUP)); } -int vt_disallocate(const char *name) { - const char *e; - int r; - - /* Deallocate the VT if possible. If not possible - * (i.e. because it is the active one), at least clear it - * entirely (including the scrollback buffer). */ +int vt_disallocate(const char *tty_path) { + assert(tty_path); - e = path_startswith(name, "/dev/"); - if (!e) - return -EINVAL; + /* Deallocate the VT if possible. If not possible (i.e. because it is the active one), at least clear + * it entirely (including the scrollback buffer). */ - if (tty_is_vc(name)) { - _cleanup_close_ int fd = -EBADF; - unsigned u; - const char *n; - - n = startswith(e, "tty"); - if (!n) - return -EINVAL; - - r = safe_atou(n, &u); - if (r < 0) - return r; - - if (u <= 0) - return -EINVAL; - - /* Try to deallocate */ - fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK); + int ttynr = vtnr_from_tty(tty_path); + if (ttynr > 0) { + _cleanup_close_ int fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK); if (fd < 0) return fd; - r = ioctl(fd, VT_DISALLOCATE, u); - if (r >= 0) + /* Try to deallocate */ + if (ioctl(fd, VT_DISALLOCATE, ttynr) >= 0) return 0; if (errno != EBUSY) return -errno; } - /* So this is not a VT (in which case we cannot deallocate it), - * or we failed to deallocate. Let's at least clear the screen. */ + /* So this is not a VT (in which case we cannot deallocate it), or we failed to deallocate. Let's at + * least clear the screen. */ - _cleanup_close_ int fd2 = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + _cleanup_close_ int fd2 = open_terminal(tty_path, O_WRONLY|O_NOCTTY|O_CLOEXEC|O_NONBLOCK); if (fd2 < 0) return fd2; - (void) loop_write(fd2, - "\033[r" /* clear scrolling region */ - "\033[H" /* move home */ - "\033[3J" /* clear screen including scrollback, requires Linux 2.6.40 */ - "\033c", /* reset to initial state */ - SIZE_MAX); - return 0; + return loop_write_full(fd2, + "\033[r" /* clear scrolling region */ + "\033[H" /* move home */ + "\033[3J" /* clear screen including scrollback, requires Linux 2.6.40 */ + "\033c", /* reset to initial state */ + SIZE_MAX, + 100 * USEC_PER_MSEC); } static int vt_default_utf8(void) {