From ef264c830effc91add6da334204215f61eb8515e Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 23 May 2013 09:25:06 +0200 Subject: [PATCH] agetty: allow full control on CLOCAL flag Now the -L option allows to explicitly enable CLOCAL flag. Unfortunately sometimes it's necessary to clear the flag. This patch add optional argument = to specify 'auto', 'always' and 'never' to control CLOCAL flag. Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=816342 Signed-off-by: Karel Zak --- term-utils/agetty.8 | 14 ++++++++++++-- term-utils/agetty.c | 44 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/term-utils/agetty.8 b/term-utils/agetty.8 index 64a1dd2..8d5286c 100644 --- a/term-utils/agetty.8 +++ b/term-utils/agetty.8 @@ -138,10 +138,20 @@ This allows the use of a non-standard login program (for example, one that asks for a dial-up password or that uses a different password file). .TP -\-L, \-\-local\-line -Force the line to be a local line with no need for carrier detect. This can +\-L, \-\-local\-line [=\fImode\fP] +Control CLOCAL line flag, the optional argument \fImode\fP is 'auto', 'always' or 'never'. +If the \fImode\fP argument is omitted then the default is 'always'. If the +\-\-local\-line option is ommitted at all then the default is 'auto'. + +The \fImode\fP 'always' forces 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. + +The \fImode\fP 'never' explicitly clears CLOCAL flags from line setting and +the carrier detect signal is expected on the line. + +The \fImode\fP 'auto' (agetty default) does not modify CLOCAL setting +and follows the setting enabled by kernel. .TP \-m, \-\-extract\-baud Try to extract the baud rate the CONNECT status message diff --git a/term-utils/agetty.c b/term-utils/agetty.c index dd52f70..0d01e7e 100644 --- a/term-utils/agetty.c +++ b/term-utils/agetty.c @@ -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 */ @@ -314,7 +321,8 @@ int main(int argc, char **argv) strlen(options.initstring)); } - if (!serial_tty_option(&options, F_LOCAL)) + if ((options.flags & F_VCONSOLE) == 0 && + options.clocal == CLOCAL_MODE_ALWAYS) /* Go to blocking write mode unless -L is specified. */ fcntl(STDOUT_FILENO, F_SETFL, fcntl(STDOUT_FILENO, F_GETFL, 0) & ~O_NONBLOCK); @@ -541,7 +549,7 @@ static void parse_args(int argc, char **argv, struct options *op) { "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' }, @@ -610,7 +618,18 @@ static void parse_args(int argc, char **argv, struct options *op) 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; @@ -1097,8 +1116,19 @@ static void termio_init(struct options *op, struct termios *tp) 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[=]*/ + 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 @@ -1655,7 +1685,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out) fputs(_(" -i, --noissue do not display issue file\n"), out); fputs(_(" -I, --init-string set init string\n"), out); fputs(_(" -l, --login-program specify login program\n"), out); - fputs(_(" -L, --local-line force local line\n"), out); + fputs(_(" -L, --local-line[=] 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 options that are passed to login\n"), out); -- 1.8.1.4