git diff v2.18..HEAD login-utils/agetty.c login-utils/agetty.8 agetty: fix -s option (baud rate setup) agetty: add -c to reuse cflags agetty: add -s to reuse existing baud rate diff --git a/login-utils/agetty.8 b/login-utils/agetty.8 index 8761374..084086f 100644 --- a/login-utils/agetty.8 +++ b/login-utils/agetty.8 @@ -3,7 +3,7 @@ agetty \- alternative Linux getty .SH SYNOPSIS -.BR "agetty " [\-8ihLmnUw] +.BR "agetty " [\-c8ihLmnsUw] .RI "[-f " issue_file ] .RI "[-l " login_program ] .RI "[-I " init ] @@ -12,16 +12,6 @@ agetty \- alternative Linux getty .I port .I baud_rate,... .RI [ term ] -.br -.BR "agetty " [\-8ihLmnw] -.RI "[-f " issue_file ] -.RI "[-l " login_program ] -.RI "[-I " init ] -.RI "[-t " timeout ] -.RI "[-H " login_host ] -.I baud_rate,... -.I port -.RI [ term ] .SH DESCRIPTION .ad @@ -92,6 +82,10 @@ whatever init(8) may have set, and is inherited by login and the shell. .fi .ad .TP +\-c +Don't reset terminal cflags (control modes). See \fItermios(3)\fP for more +details. +.TP \-8 Assume that the tty is 8-bit clean, hence disable parity detection. .TP @@ -163,6 +157,10 @@ Force the line to be a local line with no need for carrier detect. This can be useful when you have a locally attached terminal where the serial line does not set the carrier detect signal. .TP +\-s +Try to keep the existing baud rate. The baud rates from +the command line are used when agetty receives a BREAK character. +.TP \-U Turn on support for detecting an uppercase only terminal. This setting will detect a login name containing only capitals as indicating an uppercase diff --git a/login-utils/agetty.c b/login-utils/agetty.c index 39a1fd3..9d463ce 100644 --- a/login-utils/agetty.c +++ b/login-utils/agetty.c @@ -133,6 +133,8 @@ struct options { #define F_CUSTISSUE (1<<6) /* give alternative issue file */ #define F_NOPROMPT (1<<7) /* don't ask for login name! */ #define F_LCUC (1<<8) /* Support for *LCUC stty modes */ +#define F_KEEPSPEED (1<<9) /* Follow baud rate from kernel */ +#define F_KEEPCFLAGS (1<<10) /* Reuse c_cflags setup from kernel */ /* Storage for things detected while the login name was read. */ @@ -203,7 +205,7 @@ void parse_args P_((int argc, char **argv, struct options *op)); void parse_speeds P_((struct options *op, char *arg)); void update_utmp P_((char *line)); void open_tty P_((char *tty, struct termios *tp, int local)); -void termio_init P_((struct termios *tp, int speed, struct options *op)); +void termio_init P_((struct termios *tp, struct options *op)); void auto_baud P_((struct termios *tp)); void do_prompt P_((struct options *op, struct termios *tp)); void next_speed P_((struct termios *tp, struct options *op)); @@ -297,7 +299,7 @@ main(argc, argv) tcsetpgrp(0, getpid()); /* Initialize the termios settings (raw mode, eight-bit, blocking i/o). */ debug("calling termio_init\n"); - termio_init(&termios, options.speeds[FIRST_SPEED], &options); + termio_init(&termios, &options); /* write the modem init string and DON'T flush the buffers */ if (options.flags & F_INITSTRING) { @@ -373,8 +375,11 @@ parse_args(argc, argv, op) extern int optind; /* getopt */ int c; - while (isascii(c = getopt(argc, argv, "8I:LH:f:hil:mt:wUn"))) { + while (isascii(c = getopt(argc, argv, "8cI:LH:f:hil:mst:wUn"))) { switch (c) { + case 'c': + op->flags |= F_KEEPCFLAGS; + break; case '8': op->eightbits = 1; break; @@ -443,6 +448,9 @@ parse_args(argc, argv, op) case 'n': op->flags |= F_NOPROMPT; break; + case 's': + op->flags |= F_KEEPSPEED; /* keep kernel defined speed */ + break; case 't': /* time out */ if ((op->timeout = atoi(optarg)) <= 0) error(_("bad timeout value: %s"), optarg); @@ -691,11 +699,17 @@ char gbuf[1024]; char area[1024]; void -termio_init(tp, speed, op) +termio_init(tp, op) struct termios *tp; - int speed; struct options *op; { + speed_t ispeed, ospeed; + + if (op->flags & F_KEEPSPEED) { + ispeed = cfgetispeed(tp); /* save the original setting */ + ospeed = cfgetospeed(tp); + } else + ospeed = ispeed = op->speeds[FIRST_SPEED]; /* * Initial termios settings: 8-bit characters, raw-mode, blocking i/o. @@ -706,14 +720,21 @@ termio_init(tp, speed, op) /* flush input and output queues, important for modems! */ (void) tcflush(0, TCIOFLUSH); - tp->c_cflag = CS8 | HUPCL | CREAD; - cfsetispeed(tp, speed); - cfsetospeed(tp, speed); + tp->c_iflag = tp->c_lflag = tp->c_oflag = 0; + + if (!(op->flags & F_KEEPCFLAGS)) + tp->c_cflag = CS8 | HUPCL | CREAD | (tp->c_cflag & CLOCAL); + + /* Note that the speed is stored in the c_cflag termios field, so we have + * set the speed always when the cflag se reseted. + */ + cfsetispeed(tp, ispeed); + cfsetospeed(tp, ospeed); + if (op->flags & F_LOCAL) { tp->c_cflag |= CLOCAL; } - tp->c_iflag = tp->c_lflag = tp->c_oflag = 0; #ifdef HAVE_STRUCT_TERMIOS_C_LINE tp->c_line = 0; #endif @@ -973,9 +994,18 @@ next_speed(tp, op) struct termios *tp; struct options *op; { - static int baud_index = FIRST_SPEED;/* current speed index */ + static int baud_index = -1; + + if (baud_index == -1) + /* + * if the F_KEEPSPEED flags is set then the FIRST_SPEED is not + * tested yet (see termio_init()). + */ + baud_index = (op->flags & F_KEEPSPEED) ? FIRST_SPEED : + 1 % op->numspeed; + else + baud_index = (baud_index + 1) % op->numspeed; - baud_index = (baud_index + 1) % op->numspeed; cfsetispeed(tp, op->speeds[baud_index]); cfsetospeed(tp, op->speeds[baud_index]); (void) tcsetattr(0, TCSANOW, tp); @@ -1203,7 +1233,7 @@ bcode(s) void usage() { - fprintf(stderr, _("Usage: %s [-8hiLmUw] [-l login_program] [-t timeout] [-I initstring] [-H login_host] baud_rate,... line [termtype]\nor\t[-hiLmw] [-l login_program] [-t timeout] [-I initstring] [-H login_host] line baud_rate,... [termtype]\n"), progname); + fprintf(stderr, _("Usage: %s [-8hiLmsUw] [-l login_program] [-t timeout] [-I initstring] [-H login_host] baud_rate,... line [termtype]\nor\t[-hiLmw] [-l login_program] [-t timeout] [-I initstring] [-H login_host] line baud_rate,... [termtype]\n"), progname); exit(1); }