dcavalca / rpms / util-linux

Forked from rpms/util-linux 2 years ago
Clone
9d84b2
diff -up util-linux-2.23.2/term-utils/agetty.c.kzak util-linux-2.23.2/term-utils/agetty.c
9d84b2
--- util-linux-2.23.2/term-utils/agetty.c.kzak	2013-07-30 11:14:18.124912322 +0200
9d84b2
+++ util-linux-2.23.2/term-utils/agetty.c	2013-09-09 09:07:46.406689270 +0200
9d84b2
@@ -132,13 +132,20 @@ struct options {
9d84b2
 	int delay;			/* Sleep seconds before prompt */
9d84b2
 	int nice;			/* Run login with this priority */
9d84b2
 	int numspeed;			/* number of baud rates to try */
9d84b2
+	int clocal;			/* CLOCAL_MODE_* */
9d84b2
 	speed_t speeds[MAX_SPEED];	/* baud rates to be tried */
9d84b2
 };
9d84b2
 
9d84b2
+enum {
9d84b2
+	CLOCAL_MODE_AUTO = 0,
9d84b2
+	CLOCAL_MODE_ALWAYS,
9d84b2
+	CLOCAL_MODE_NEVER
9d84b2
+};
9d84b2
+
9d84b2
 #define	F_PARSE		(1<<0)	/* process modem status messages */
9d84b2
 #define	F_ISSUE		(1<<1)	/* display /etc/issue */
9d84b2
 #define	F_RTSCTS	(1<<2)	/* enable RTS/CTS flow control */
9d84b2
-#define F_LOCAL		(1<<3)	/* force local */
9d84b2
+
9d84b2
 #define F_INITSTRING    (1<<4)	/* initstring is set */
9d84b2
 #define F_WAITCRLF	(1<<5)	/* wait for CR or LF */
9d84b2
 #define F_CUSTISSUE	(1<<6)	/* give alternative issue file */
9d84b2
@@ -235,10 +242,13 @@ static void login_options_to_argv(char *
9d84b2
 static char *fakehost;
9d84b2
 
9d84b2
 #ifdef DEBUGGING
9d84b2
-#define debug(s) do { fprintf(dbf,s); fflush(dbf); } while (0)
9d84b2
+# ifndef DEBUG_OUTPUT
9d84b2
+#  define DEBUG_OUTPUT "/dev/ttyp0"
9d84b2
+# endif
9d84b2
+# define debug(s) do { fprintf(dbf,s); fflush(dbf); } while (0)
9d84b2
 FILE *dbf;
9d84b2
 #else
9d84b2
-#define debug(s) do { ; } while (0)
9d84b2
+# define debug(s) do { ; } while (0)
9d84b2
 #endif
9d84b2
 
9d84b2
 int main(int argc, char **argv)
9d84b2
@@ -270,7 +280,7 @@ int main(int argc, char **argv)
9d84b2
 	sigaction(SIGINT, &sa, &sa_int);
9d84b2
 
9d84b2
 #ifdef DEBUGGING
9d84b2
-	dbf = fopen("/dev/ttyp0", "w");
9d84b2
+	dbf = fopen(DEBUG_OUTPUT, "w");
9d84b2
 	for (int i = 1; i < argc; i++)
9d84b2
 		debug(argv[i]);
9d84b2
 #endif				/* DEBUGGING */
9d84b2
@@ -311,8 +321,10 @@ int main(int argc, char **argv)
9d84b2
 			   strlen(options.initstring));
9d84b2
 	}
9d84b2
 
9d84b2
-	if (!serial_tty_option(&options, F_LOCAL))
9d84b2
-		/* Go to blocking write mode unless -L is specified. */
9d84b2
+	if (options.flags & F_VCONSOLE || options.clocal != CLOCAL_MODE_ALWAYS)
9d84b2
+		/* Go to blocking mode unless -L is specified, this change
9d84b2
+		 * affects stdout, stdin and stderr as all the file descriptors
9d84b2
+		 * are created by dup().   */
9d84b2
 		fcntl(STDOUT_FILENO, F_SETFL,
9d84b2
 		      fcntl(STDOUT_FILENO, F_GETFL, 0) & ~O_NONBLOCK);
9d84b2
 
9d84b2
@@ -420,6 +432,12 @@ int main(int argc, char **argv)
9d84b2
 				options.tty);
9d84b2
 	}
9d84b2
 
9d84b2
+#ifdef DEBUGGING
9d84b2
+	fprintf(dbf, "read %c\n", ch);
9d84b2
+	if (close_stream(dbf) != 0)
9d84b2
+		log_err("write failed: %s", DEBUG_OUTPUT);
9d84b2
+#endif
9d84b2
+
9d84b2
 	/* Let the login program take care of password validation. */
9d84b2
 	execv(options.login, login_argv);
9d84b2
 	log_err(_("%s: can't exec %s: %m"), options.tty, login_argv[0]);
9d84b2
@@ -534,7 +552,7 @@ static void parse_args(int argc, char **
9d84b2
 		{  "init-string",    required_argument,  0,  'I'  },
9d84b2
 		{  "noclear",	     no_argument,	 0,  'J'  },
9d84b2
 		{  "login-program",  required_argument,  0,  'l'  },
9d84b2
-		{  "local-line",     no_argument,	 0,  'L'  },
9d84b2
+		{  "local-line",     optional_argument,	 0,  'L'  },
9d84b2
 		{  "extract-baud",   no_argument,	 0,  'm'  },
9d84b2
 		{  "skip-login",     no_argument,	 0,  'n'  },
9d84b2
 		{  "nonewline",	     no_argument,	 0,  'N'  },
9d84b2
@@ -603,7 +621,18 @@ static void parse_args(int argc, char **
9d84b2
 			op->login = optarg;
9d84b2
 			break;
9d84b2
 		case 'L':
9d84b2
-			op->flags |= F_LOCAL;
9d84b2
+			/* -L and -L=always have the same meaning */
9d84b2
+			op->clocal = CLOCAL_MODE_ALWAYS;
9d84b2
+			if (optarg) {
9d84b2
+				if (strcmp(optarg, "=always") == 0)
9d84b2
+					op->clocal = CLOCAL_MODE_ALWAYS;
9d84b2
+				else if (strcmp(optarg, "=never") == 0)
9d84b2
+					op->clocal = CLOCAL_MODE_NEVER;
9d84b2
+				else if (strcmp(optarg, "=auto") == 0)
9d84b2
+					op->clocal = CLOCAL_MODE_AUTO;
9d84b2
+				else
9d84b2
+					log_err(_("unssuported --local-line mode argument"));
9d84b2
+			}
9d84b2
 			break;
9d84b2
 		case 'm':
9d84b2
 			op->flags |= F_PARSE;
9d84b2
@@ -1090,8 +1119,19 @@ static void termio_init(struct options *
9d84b2
 	cfsetispeed(tp, ispeed);
9d84b2
 	cfsetospeed(tp, ospeed);
9d84b2
 
9d84b2
-	if (op->flags & F_LOCAL)
9d84b2
-		tp->c_cflag |= CLOCAL;
9d84b2
+	/* The default is to follow setting from kernel, but it's possible
9d84b2
+	 * to explicitly remove/add CLOCAL flag by -L[=<mode>]*/
9d84b2
+	switch (op->clocal) {
9d84b2
+	case CLOCAL_MODE_ALWAYS:
9d84b2
+		tp->c_cflag |= CLOCAL;		/* -L or -L=always */
9d84b2
+		break;
9d84b2
+	case CLOCAL_MODE_NEVER:
9d84b2
+		tp->c_cflag &= ~CLOCAL;		/* -L=never */
9d84b2
+		break;
9d84b2
+	case CLOCAL_MODE_AUTO:			/* -L=auto */
9d84b2
+		break;
9d84b2
+	}
9d84b2
+
9d84b2
 #ifdef HAVE_STRUCT_TERMIOS_C_LINE
9d84b2
 	tp->c_line = 0;
9d84b2
 #endif
9d84b2
@@ -1412,9 +1452,10 @@ static char *get_logname(struct options
9d84b2
 
9d84b2
 			if (read(STDIN_FILENO, &c, 1) < 1) {
9d84b2
 
9d84b2
-				/* Do not report trivial like EINTR/EIO errors. */
9d84b2
+				/* The terminal could be open with O_NONBLOCK when
9d84b2
+				 * -L (force CLOCAL) is specified...  */
9d84b2
 				if (errno == EINTR || errno == EAGAIN) {
9d84b2
-					usleep(1000);
9d84b2
+					usleep(250000);
9d84b2
 					continue;
9d84b2
 				}
9d84b2
 				switch (errno) {
9d84b2
@@ -1648,7 +1689,7 @@ static void __attribute__ ((__noreturn__
9d84b2
 	fputs(_(" -i, --noissue              do not display issue file\n"), out);
9d84b2
 	fputs(_(" -I, --init-string <string> set init string\n"), out);
9d84b2
 	fputs(_(" -l, --login-program <file> specify login program\n"), out);
9d84b2
-	fputs(_(" -L, --local-line           force local line\n"), out);
9d84b2
+	fputs(_(" -L, --local-line[=<mode>]  cotrol local line flag\n"), out);
9d84b2
 	fputs(_(" -m, --extract-baud         extract baud rate during connect\n"), out);
9d84b2
 	fputs(_(" -n, --skip-login           do not prompt for login\n"), out);
9d84b2
 	fputs(_(" -o, --login-options <opts> options that are passed to login\n"), out);