]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
login: Restore tty size after calling vhangup()
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Sat, 30 Oct 2021 14:56:14 +0000 (15:56 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 2 Nov 2021 11:08:07 +0000 (11:08 +0000)
If login receives the tty to work on via stdin, stdout and stderr,
login might end up closing the remaining open file descriptors to
the tty just before it calls vhangup(). When the last open file
descriptors to a tty are closed, it's configured size is reset to
0x0. To avoid this from happening, save the size before closing
the stdin, stdout and stderr file descriptors and reapply the size
after the tty is re-opened.

Fixes #1484

login-utils/login.c

index c6cd340b69289db3d5ed0d2307c6e477a92c13a6..975a37943c63a34f9c6a92d27b11d70cee4ebeda 100644 (file)
@@ -513,6 +513,7 @@ static void init_tty(struct login_context *cxt)
 {
        struct stat st;
        struct termios tt, ttt;
+       struct winsize ws;
 
        cxt->tty_mode = (mode_t) getlogindefs_num("TTYPERM", TTY_MODE);
 
@@ -543,6 +544,12 @@ static void init_tty(struct login_context *cxt)
        }
 #endif
 
+       /* The TTY size might be reset to 0x0 by the kernel when we close the stdin/stdout/stderr file
+        * descriptors so let's save the size now so we can reapply it later */
+       memset(&ws, 0, sizeof(struct winsize));
+       if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0)
+               syslog(LOG_WARNING, _("TIOCGWINSZ ioctl failed: %m"));
+
        tcgetattr(0, &tt);
        ttt = tt;
        ttt.c_cflag &= ~HUPCL;
@@ -574,6 +581,11 @@ static void init_tty(struct login_context *cxt)
 
        /* restore tty modes */
        tcsetattr(0, TCSAFLUSH, &tt);
+
+       /* Restore tty size */
+       if (ws.ws_row > 0 || ws.ws_col > 0)
+               if (ioctl(STDIN_FILENO, TIOCSWINSZ, &ws) < 0)
+                       syslog(LOG_WARNING, _("TIOCSWINSZ ioctl failed: %m"));
 }
 
 /*