]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
terminal-util: refactor vt_disallocate()
authorLennart Poettering <lennart@poettering.net>
Thu, 11 Jul 2024 15:45:34 +0000 (17:45 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 19 Jul 2024 09:44:04 +0000 (11:44 +0200)
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)

src/basic/terminal-util.c

index 4c9816d9698617a8b402d67163de447f6c866b9b..d8253037ec452a9ba54927ba39e83fd61e00f0db 100644 (file)
@@ -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) {