File: 10agetty.dpatch

package info (click to toggle)
util-linux 2.12r-19etch1
  • links: PTS
  • area: main
  • in suites: etch
  • size: 8,932 kB
  • ctags: 5,101
  • sloc: ansic: 46,134; sh: 8,074; makefile: 1,111; perl: 86; csh: 62; sed: 55
file content (122 lines) | stat: -rw-r--r-- 3,516 bytes parent folder | download | duplicates (2)
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);