From: LaMont Jones Date: Tue, 17 Jul 2007 23:26:02 +0000 (-0600) Subject: agetty historical (and broken) code X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=68f2810e53cab1468d4c6fb114cb76ac0e7bcd5a;p=util-linux agetty historical (and broken) code --- diff --git a/login-utils/agetty.c b/login-utils/agetty.c index b7ae536f..7d5d81b3 100644 --- a/login-utils/agetty.c +++ b/login-utils/agetty.c @@ -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 +#include + 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);