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