getty: fix a minor problem of Ctrl-D not printing '\n'
Also removed defines for control chars which are never changed, and added login/getty README. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
ee320c6d9c
commit
e9dc354df8
70
loginutils/README
Normal file
70
loginutils/README
Normal file
@ -0,0 +1,70 @@
|
||||
Getty
|
||||
|
||||
??? Should getty open tty with or without O_NONBLOCK?
|
||||
For serial lines, it means "should getty wait for Carrier Detect pin?"
|
||||
I checked other getties:
|
||||
|
||||
- agetty always uses O_NONBLOCK
|
||||
- mgetty uses O_NONBLOCK unless run with -b, or as "getty"
|
||||
|
||||
??? If we decided to use O_NONBLOCK (perhaps optionally with -b),
|
||||
when getty should send -I INITSTR data to tty? After open succeeds?
|
||||
What if we also want to initialize *modem* with some AT commands?
|
||||
|
||||
??? Should we check/create /var/lock/LCK..ttyPFX lockfiles?
|
||||
|
||||
??? mgetty opens tty but does NOT lock it, then waits for input via
|
||||
select/poll, and when input is available, it checks lock file.
|
||||
If it exists, mgetty exits (it assumes someone else uses the line).
|
||||
If no, it creates the file (lock the tty). Sounds like a good algorithm
|
||||
to use if we are called with -w...
|
||||
|
||||
Getty should establish a new session and process group, and ensure
|
||||
that tty is a ctty.
|
||||
|
||||
??? Should getty ensure that other processes which might have opened
|
||||
fds to this tty be dusconnected? agetty has a -R option which makes
|
||||
agetty call vhangup() after tty is opened. (Then agetty opens it again,
|
||||
since it probably vhangup'ed its own fd too).
|
||||
|
||||
Getty should leave the tty in approximately the same state as "stty sane"
|
||||
before it execs login program. Minor things we do conditionally are:
|
||||
c_iflag |= ICRNL; // if '\r' was used to end username
|
||||
|
||||
??? mgetty uses per-tty file to ignore connects, /etc/nologin.ttyxx -
|
||||
is it useful?
|
||||
|
||||
It should be possible to run "getty 0 -" from a shell prompt.
|
||||
[This currently doesn't work from interactive shell since setsid()
|
||||
fails in process group leader. The workaround is to run it as a child
|
||||
of something. sh -c 'getty - 0; true' usually works. Should we fix this?]
|
||||
It should leave tty in a sane state when it exits (Ctrl-D, -t SEC timeout):
|
||||
echo should be on, speed, control chars properly set, etc.
|
||||
(However, it can't restore ctty. The symptom is that "</dev/tty"
|
||||
fails in the parent shell after getty exits: /dev/tty can't be opened).
|
||||
|
||||
Getty should write LOGIN_PROCESS utmp record before it starts waiting
|
||||
for username to be entered.
|
||||
|
||||
Login
|
||||
|
||||
Login should not try to set up tty parameters - apart from switching echo
|
||||
off while entering password, and switching it back on after.
|
||||
|
||||
Login should not leave "echo off" state when it times out reading password
|
||||
or otherwise terminates (Ctrl-C, Ctrl-D etc).
|
||||
|
||||
??? Should login establish a new session and/or process group, and ensure
|
||||
that tty is a ctty? Without this, running login directly (not via getty)
|
||||
from e.g. initscript will usually result with a login session without
|
||||
ctty and without session/pgrp properly created...
|
||||
|
||||
It should be possible to run "login [USER]" from a shell prompt,
|
||||
and it should work (not block/die/error out).
|
||||
Similarly to getty, it should leave tty in the sane state when it exits.
|
||||
|
||||
??? Should login write LOGIN_PROCESS utmp record before it starts waiting
|
||||
for username/password to be entered?
|
||||
|
||||
Login should write USER_PROCESS utmp record just before it is about
|
||||
to exec user's shell.
|
@ -63,18 +63,8 @@ static FILE *dbf;
|
||||
*/
|
||||
#define ISSUE "/etc/issue"
|
||||
|
||||
/* Some shorthands for control characters */
|
||||
#define CTL(x) ((x) ^ 0100) /* Assumes ASCII dialect */
|
||||
#define BS CTL('H') /* back space */
|
||||
#define DEL CTL('?') /* delete */
|
||||
|
||||
/* Defaults for line-editing etc. characters; you may want to change this */
|
||||
#define DEF_INTR CTL('C') /* default interrupt character */
|
||||
#define DEF_QUIT CTL('\\') /* default quit char */
|
||||
#define DEF_KILL CTL('U') /* default kill char */
|
||||
#define DEF_EOF CTL('D') /* default EOF char */
|
||||
#define DEF_EOL '\n'
|
||||
#define DEF_SWITCH 0 /* default switch char (none) */
|
||||
/* Macro to build Ctrl-LETTER. Assumes ASCII dialect */
|
||||
#define CTL(x) ((x) ^ 0100)
|
||||
|
||||
/*
|
||||
* When multiple baud rates are specified on the command line,
|
||||
@ -365,17 +355,17 @@ static void finalize_tty_attrs(void)
|
||||
* (why "stty sane" unsets this bit?)
|
||||
*/
|
||||
|
||||
G.tty_attrs.c_cc[VINTR] = DEF_INTR;
|
||||
G.tty_attrs.c_cc[VQUIT] = DEF_QUIT;
|
||||
G.tty_attrs.c_cc[VEOF] = DEF_EOF;
|
||||
G.tty_attrs.c_cc[VEOL] = DEF_EOL;
|
||||
G.tty_attrs.c_cc[VINTR] = CTL('C');
|
||||
G.tty_attrs.c_cc[VQUIT] = CTL('\\');
|
||||
G.tty_attrs.c_cc[VEOF] = CTL('D');
|
||||
G.tty_attrs.c_cc[VEOL] = '\n';
|
||||
#ifdef VSWTC
|
||||
G.tty_attrs.c_cc[VSWTC] = DEF_SWITCH;
|
||||
G.tty_attrs.c_cc[VSWTC] = 0;
|
||||
#endif
|
||||
#ifdef VSWTCH
|
||||
G.tty_attrs.c_cc[VSWTCH] = DEF_SWITCH;
|
||||
G.tty_attrs.c_cc[VSWTCH] = 0;
|
||||
#endif
|
||||
G.tty_attrs.c_cc[VKILL] = DEF_KILL;
|
||||
G.tty_attrs.c_cc[VKILL] = CTL('U');
|
||||
/* Other control chars:
|
||||
* VEOL2
|
||||
* VERASE, VWERASE - (word) erase. we may set VERASE in get_logname
|
||||
@ -386,6 +376,9 @@ static void finalize_tty_attrs(void)
|
||||
*/
|
||||
|
||||
set_tty_attrs();
|
||||
|
||||
/* Now the newline character should be properly written */
|
||||
full_write(STDOUT_FILENO, "\n", 1);
|
||||
}
|
||||
|
||||
/* extract baud rate from modem status message */
|
||||
@ -449,8 +442,7 @@ static char *get_logname(void)
|
||||
tcflush(STDIN_FILENO, TCIFLUSH);
|
||||
|
||||
/* Prompt for and read a login name */
|
||||
G.line_buf[0] = '\0';
|
||||
while (!G.line_buf[0]) {
|
||||
do {
|
||||
/* Write issue file and prompt */
|
||||
#ifdef ISSUE
|
||||
if (!(option_mask32 & F_NOISSUE))
|
||||
@ -458,9 +450,8 @@ static char *get_logname(void)
|
||||
#endif
|
||||
print_login_prompt();
|
||||
|
||||
/* Read name, watch for break, parity, erase, kill, end-of-line */
|
||||
/* Read name, watch for break, erase, kill, end-of-line */
|
||||
bp = G.line_buf;
|
||||
G.eol = '\0';
|
||||
while (1) {
|
||||
/* Do not report trivial EINTR/EIO errors */
|
||||
errno = EINTR; /* make read of 0 bytes be silent too */
|
||||
@ -471,20 +462,14 @@ static char *get_logname(void)
|
||||
bb_perror_msg_and_die(bb_msg_read_error);
|
||||
}
|
||||
|
||||
/* BREAK. If we have speeds to try,
|
||||
* return NULL (will switch speeds and return here) */
|
||||
if (c == '\0' && G.numspeed > 1)
|
||||
return NULL;
|
||||
|
||||
/* Do erase, kill and end-of-line processing */
|
||||
switch (c) {
|
||||
case '\r':
|
||||
case '\n':
|
||||
*bp = '\0';
|
||||
G.eol = c;
|
||||
goto got_logname;
|
||||
case BS:
|
||||
case DEL:
|
||||
case CTL('H'):
|
||||
case 0x7f:
|
||||
G.tty_attrs.c_cc[VERASE] = c;
|
||||
if (bp > G.line_buf) {
|
||||
full_write(STDOUT_FILENO, "\010 \010", 3);
|
||||
@ -497,9 +482,16 @@ static char *get_logname(void)
|
||||
bp--;
|
||||
}
|
||||
break;
|
||||
case CTL('C'):
|
||||
case CTL('D'):
|
||||
finalize_tty_attrs();
|
||||
exit(EXIT_SUCCESS);
|
||||
case '\0':
|
||||
/* BREAK. If we have speeds to try,
|
||||
* return NULL (will switch speeds and return here) */
|
||||
if (G.numspeed > 1)
|
||||
return NULL;
|
||||
/* fall through and ignore it */
|
||||
default:
|
||||
if ((unsigned char)c < ' ') {
|
||||
/* ignore garbage characters */
|
||||
@ -512,7 +504,7 @@ static char *get_logname(void)
|
||||
}
|
||||
} /* end of get char loop */
|
||||
got_logname: ;
|
||||
} /* while logname is empty */
|
||||
} while (G.line_buf[0] == '\0'); /* while logname is empty */
|
||||
|
||||
return G.line_buf;
|
||||
}
|
||||
@ -682,9 +674,6 @@ int getty_main(int argc UNUSED_PARAM, char **argv)
|
||||
|
||||
finalize_tty_attrs();
|
||||
|
||||
/* Now the newline character should be properly written */
|
||||
full_write(STDOUT_FILENO, "\n", 1);
|
||||
|
||||
/* Let the login program take care of password validation */
|
||||
/* We use PATH because we trust that root doesn't set "bad" PATH,
|
||||
* and getty is not suid-root applet */
|
||||
|
@ -443,7 +443,6 @@ int login_main(int argc UNUSED_PARAM, char **argv)
|
||||
if (pw->pw_uid != 0)
|
||||
die_if_nologin();
|
||||
|
||||
|
||||
#if ENABLE_LOGIN_SESSION_AS_CHILD
|
||||
child_pid = vfork();
|
||||
if (child_pid != 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user