From 223a7c9ce0979d5886dea0b64df56655665fff6a Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 18 Nov 2011 20:39:00 +0100 Subject: agetty: support silent re-open of the tty Instead of complaining loudly that a TTY could not be opened and preventing it from working for 5 minutes, now we silently try in slow loops. This allows machines to work normally with pre-configured serial ports even if these ports are not present (eg: USB). --- term-utils/agetty.c | 74 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/term-utils/agetty.c b/term-utils/agetty.c index 4c1ed04..a3497c0 100644 --- a/term-utils/agetty.c.old +++ b/term-utils/agetty.c @@ -1013,34 +1013,61 @@ static void open_tty(char *tty, struct t if (len < 0 || (size_t)len >= sizeof(buf)) log_err(_("/dev/%s: cannot open as standard input: %m"), tty); - /* Open the tty as standard input. */ - if ((fd = open(buf, O_RDWR|O_NOCTTY|O_NONBLOCK, 0)) < 0) - log_err(_("/dev/%s: cannot open as standard input: %m"), tty); - - /* - * There is always a race between this reset and the call to - * vhangup() that s.o. can use to get access to your tty. - * Linux login(1) will change tty permissions. Use root owner and group - * with permission -rw------- for the period between getty and login. + /* We loop forever trying to open the device every 5 seconds in case it + * spontaneously appears (eg: USB device). */ - if (fchown(fd, 0, gid) || fchmod(fd, (gid ? 0620 : 0600))) { - if (errno == EROFS) - log_warn("%s: %m", buf); - else - log_err("%s: %m", buf); - } + for (;; sleep(5)) { + /* Open the tty as standard input. */ + if ((fd = open(buf, O_RDWR|O_NOCTTY|O_NONBLOCK, 0)) < 0) { + //log_err(_("/dev/%s: cannot open as standard input: %m"), tty); + continue; + } + + /* + * There is always a race between this reset and the call to + * vhangup() that s.o. can use to get access to your tty. + * Linux login(1) will change tty permissions. Use root owner and group + * with permission -rw------- for the period between getty and login. + */ + if (fchown(fd, 0, gid) || fchmod(fd, (gid ? 0620 : 0600))) { + if (errno == EROFS) { + //log_warn("%s: %m", buf); + } + else { + close(fd); + continue; + // log_err("%s: %m", buf); + } + } + + /* Sanity checks... */ + if (fstat(fd, &st) < 0) { + close(fd); + continue; + // log_err("%s: %m", buf); + } + + if ((st.st_mode & S_IFMT) != S_IFCHR) { + close(fd); + continue; + // log_err(_("/dev/%s: not a character device"), tty); + } + + if (!isatty(fd)) { + close(fd); + continue; + // log_err(_("/dev/%s: not a tty"), tty); + } - /* Sanity checks... */ - if (fstat(fd, &st) < 0) - log_err("%s: %m", buf); - if ((st.st_mode & S_IFMT) != S_IFCHR) - log_err(_("/dev/%s: not a character device"), tty); - if (!isatty(fd)) - log_err(_("/dev/%s: not a tty"), tty); - - if (((tid = tcgetsid(fd)) < 0) || (pid != tid)) { - if (ioctl(fd, TIOCSCTTY, 1) == -1) - log_warn(_("/dev/%s: cannot get controlling tty: %m"), tty); + if (((tid = tcgetsid(fd)) < 0) || (pid != tid)) { + if (ioctl(fd, TIOCSCTTY, 1) == -1) { + close(fd); + continue; + // log_warn(_("/dev/%s: cannot get controlling tty: %m"), tty); + } + } + /* Excellent, our new terminal is open and ready */ + break; } close(STDIN_FILENO);