]> err.no Git - util-linux/commitdiff
agetty historical (and broken) code
authorLaMont Jones <lamont@mmjgroup.com>
Tue, 17 Jul 2007 23:26:02 +0000 (17:26 -0600)
committerLaMont Jones <lamont@mmjgroup.com>
Tue, 17 Jul 2007 23:26:02 +0000 (17:26 -0600)
login-utils/agetty.c

index b7ae536f0e397f774d0ce5f593757aafcc9382ff..7d5d81b3b9cb4dc570ea415f4724123ada8d0553 100644 (file)
@@ -664,6 +664,93 @@ open_tty(tty, tp, local)
        if ((st.st_mode & S_IFMT) != S_IFCHR)
            error(_("/dev/%s: not a character device"), tty);
 
+       /*
+        * Try to avoid opening a vt that is already open, as this will
+        * mean that the keyboard will be unusable.
+        *
+        * Unfortunately, all the kernel gives us to find out is an ioctl
+        * for the next available vt.  As the kernel doesn't open the vt for
+        * you with the ioctl, there is still a chance of both processes
+        * opening the same vt, but this check is far better than nothing at
+        * all.
+        *
+        * The kernel API sucks, and is unusable for this situation.  What
+        * we really need is an ioctl that says 'does anyone _ELSE_ have
+        * this tty open', and that doesn't exist.  Or better yet, the
+        * kernel really shouldn't allow two processes to have read access
+        * on the same tty at the same time (other than with dup...)  Opens
+        * of the same tty device shouldn't be able to steal reads from
+        * each other.
+        *
+        * Similar to the check added to gdm.
+        *
+        * For now, just turn off this check, restoring the bug that ?dm
+        * (and the system) occasionally get their keyboard locked out by
+        * getty showing up after they've taken a vt that inittab says
+        * goes to a getty.
+        * Bummer.
+        *
+        */
+#if 0
+       if (strncmp(tty,"tty",3) == 0)
+       {
+#include <sys/vt.h>
+#include <linux/tty.h>
+           char *end;
+           int vtno;
+
+           vtno = strtol(tty+3,&end,10);
+           if (end != tty+3 && *end == '\0' && vtno > 1)
+           {
+               int fd;
+               int newvtno;
+               int fds[MAX_NR_CONSOLES];
+               int vt_cnt = 0;
+               int i;
+
+               for ( i = 0 ; i < MAX_NR_CONSOLES ; i++ )
+                   fds[i] = -1;
+
+               if ((fd = open("/dev/tty0", O_WRONLY, 0) ) < 0
+                   && errno != ENOENT)
+                   error(_("/dev/tty0: cannot open: %m"));
+
+               if (fd >= 0) do
+               {
+                   if ((ioctl(fd, VT_OPENQRY, &newvtno ) < 0))
+                       error(_("failed to query next available vt"));
+
+                   if (newvtno == -1)
+                       error(_("all vts are in use"));
+
+                   if (newvtno > vtno)
+                       error(_("/dev/%s: already in use"), tty);
+
+                   if (newvtno < vtno)
+                   {
+                       char vtname[TTY_NAME_MAX+3];
+
+                       sprintf( vtname, "tty%d", newvtno );
+
+                       if ((fds[vt_cnt++] =
+                           open(vtname, O_RDWR|O_NONBLOCK, 0)) < 0)
+                       {
+                           error(_("/dev/%s: cannot open: %m"), tty);
+                       }
+                   }
+               } while (newvtno != vtno);
+
+               close(fd);
+               for ( i = 0 ; i < MAX_NR_CONSOLES ; i++ )
+               {
+                   if (fds[i] == -1)
+                       break;
+                   close(fds[i]);
+               }
+           }
+       }
+#endif
+
        /* Open the tty as standard input. */
 
        (void) close(0);