Even with TTYReset=no it seems with systemd or plymouth the termios flags become changed from under the first agetty on a serial system console as the flags are locked. --- agetty.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) --- term-utils/agetty.c +++ term-utils/agetty.c 2014-01-10 13:05:50.411075349 +0000 @@ -281,8 +281,9 @@ static void login_options_to_argv(char * static char *fakehost; #ifdef DEBUGGING +# include "closestream.h" # ifndef DEBUG_OUTPUT -# define DEBUG_OUTPUT "/dev/ttyp0" +# define DEBUG_OUTPUT "/dev/tty10" # endif # define debug(s) do { fprintf(dbf,s); fflush(dbf); } while (0) FILE *dbf; @@ -320,8 +321,12 @@ int main(int argc, char **argv) #ifdef DEBUGGING dbf = fopen(DEBUG_OUTPUT, "w"); - for (int i = 1; i < argc; i++) + for (int i = 1; i < argc; i++) { + if (i > 1) + debug(" "); debug(argv[i]); + } + debug("\n"); #endif /* DEBUGGING */ /* Parse command-line arguments. */ @@ -473,7 +478,6 @@ int main(int argc, char **argv) if (options.osrelease) free(options.osrelease); #ifdef DEBUGGING - fprintf(dbf, "read %c\n", ch); if (close_stream(dbf) != 0) log_err("write failed: %s", DEBUG_OUTPUT); #endif @@ -1090,6 +1094,25 @@ static void termio_init(struct options * { speed_t ispeed, ospeed; struct winsize ws; + struct termios lock; + int i; + + for (i = 0; i < 20; i++) { + /* + * Even with TTYReset=no it seems with systemd or plymouth + * the termios flags become changed from under the first + * agetty on a serial system console as the flags are locked. + */ + memset(&lock, 0, sizeof(struct termios)); + if (ioctl(STDIN_FILENO, TIOCGLCKTRMIOS, &lock) < 0) + break; + if (!lock.c_iflag && !lock.c_oflag && !lock.c_cflag && !lock.c_lflag) + break; + debug("termios locked\n"); + sleep(1); + } + memset(&lock, 0, sizeof(struct termios)); + ioctl(STDIN_FILENO, TIOCSLCKTRMIOS, &lock); if (op->flags & F_VCONSOLE) { #if defined(IUTF8) && defined(KDGKBMODE) @@ -1154,9 +1177,6 @@ static void termio_init(struct options * * later on. */ - /* Flush input and output queues, important for modems! */ - tcflush(STDIN_FILENO, TCIOFLUSH); - #ifdef IUTF8 tp->c_iflag = tp->c_iflag & IUTF8; if (tp->c_iflag & IUTF8) @@ -1216,8 +1236,11 @@ static void termio_init(struct options * if (op->flags & F_RTSCTS) tp->c_cflag |= CRTSCTS; #endif + /* Flush input and output queues, important for modems! */ + tcflush(STDIN_FILENO, TCIOFLUSH); - tcsetattr(STDIN_FILENO, TCSANOW, tp); + if (tcsetattr(STDIN_FILENO, TCSANOW, tp)) + log_warn(_("setting terminal attributes failed: %m")); /* Go to blocking input even in local mode. */ fcntl(STDIN_FILENO, F_SETFL, @@ -1238,6 +1261,10 @@ static void reset_vc(const struct option if (tcsetattr(STDIN_FILENO, TCSADRAIN, tp)) log_warn(_("setting terminal attributes failed: %m")); + + /* Go to blocking input even in local mode. */ + fcntl(STDIN_FILENO, F_SETFL, + fcntl(STDIN_FILENO, F_GETFL, 0) & ~O_NONBLOCK); } /* Extract baud rate from modem status message. */