Sophie

Sophie

distrib > Mageia > 1 > i586 > by-pkgid > f572665e5775556b54b4c31e26347488 > files > 25

util-linux-ng-2.18-4.mga1.src.rpm

Subject: [PATCH] agetty: add -s to reuse existing baud rate
From: Andrey Borzenkov <arvidjaar@gmail.com>

For example:

	/sbin/agetty -s /dev/ttyS0 9600

will reuse the speed the kernel configured on the port. If the setting
from kernel is useless (tty returns BREAK character) then the baud
rate from command line (9600) is used.

Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=623685
Signed-off-by: Karel Zak <kzak@redhat.com>

Signed-off-by: Andrey Borzenkov <arvidjaar@gmail.com>

---

 login-utils/agetty.8 |   20 ++++++++-----------
 login-utils/agetty.c |   54 +++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 51 insertions(+), 23 deletions(-)

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);
 }