1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
#! /bin/sh /usr/share/dpatch/dpatch-run
## 10agetty.dpatch by LaMont Jones <lamont@debian.org>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: agetty changes in Debian. The biggest part is switching from
## DP: termio to termios. The only other thing is a block of turned-off
## DP: code trying to interoperate better with gdm.
@DPATCH@
diff -urNad 2.12r-16~/login-utils/agetty.c 2.12r-16/login-utils/agetty.c
--- 2.12r-16~/login-utils/agetty.c 2006-12-19 09:02:16.000000000 -0700
+++ 2.12r-16/login-utils/agetty.c 2007-01-09 11:21:56.000000000 -0700
@@ -30,6 +30,8 @@
#include <getopt.h>
#include <time.h>
#include <sys/file.h>
+#include <sys/vt.h>
+#include <linux/tty.h>
#include "xstrncpy.h"
#include "nls.h"
@@ -402,7 +404,7 @@
while (isascii(c = getopt(argc, argv, "I:LH:f:hil:mt:wn"))) {
switch (c) {
case 'I':
- if (!(op->initstring = malloc(strlen(optarg)))) {
+ if (!(op->initstring = malloc(strlen(optarg)+1))) {
error(_("can't malloc initstring"));
break;
}
@@ -652,6 +654,91 @@
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)
+ {
+ 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);
|