mirror of
https://github.com/sheumann/hush.git
synced 2024-12-23 05:29:58 +00:00
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"
|
#define ISSUE "/etc/issue"
|
||||||
|
|
||||||
/* Some shorthands for control characters */
|
/* Macro to build Ctrl-LETTER. Assumes ASCII dialect */
|
||||||
#define CTL(x) ((x) ^ 0100) /* Assumes ASCII dialect */
|
#define CTL(x) ((x) ^ 0100)
|
||||||
#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) */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When multiple baud rates are specified on the command line,
|
* 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?)
|
* (why "stty sane" unsets this bit?)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
G.tty_attrs.c_cc[VINTR] = DEF_INTR;
|
G.tty_attrs.c_cc[VINTR] = CTL('C');
|
||||||
G.tty_attrs.c_cc[VQUIT] = DEF_QUIT;
|
G.tty_attrs.c_cc[VQUIT] = CTL('\\');
|
||||||
G.tty_attrs.c_cc[VEOF] = DEF_EOF;
|
G.tty_attrs.c_cc[VEOF] = CTL('D');
|
||||||
G.tty_attrs.c_cc[VEOL] = DEF_EOL;
|
G.tty_attrs.c_cc[VEOL] = '\n';
|
||||||
#ifdef VSWTC
|
#ifdef VSWTC
|
||||||
G.tty_attrs.c_cc[VSWTC] = DEF_SWITCH;
|
G.tty_attrs.c_cc[VSWTC] = 0;
|
||||||
#endif
|
#endif
|
||||||
#ifdef VSWTCH
|
#ifdef VSWTCH
|
||||||
G.tty_attrs.c_cc[VSWTCH] = DEF_SWITCH;
|
G.tty_attrs.c_cc[VSWTCH] = 0;
|
||||||
#endif
|
#endif
|
||||||
G.tty_attrs.c_cc[VKILL] = DEF_KILL;
|
G.tty_attrs.c_cc[VKILL] = CTL('U');
|
||||||
/* Other control chars:
|
/* Other control chars:
|
||||||
* VEOL2
|
* VEOL2
|
||||||
* VERASE, VWERASE - (word) erase. we may set VERASE in get_logname
|
* VERASE, VWERASE - (word) erase. we may set VERASE in get_logname
|
||||||
@ -386,6 +376,9 @@ static void finalize_tty_attrs(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
set_tty_attrs();
|
set_tty_attrs();
|
||||||
|
|
||||||
|
/* Now the newline character should be properly written */
|
||||||
|
full_write(STDOUT_FILENO, "\n", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* extract baud rate from modem status message */
|
/* extract baud rate from modem status message */
|
||||||
@ -449,8 +442,7 @@ static char *get_logname(void)
|
|||||||
tcflush(STDIN_FILENO, TCIFLUSH);
|
tcflush(STDIN_FILENO, TCIFLUSH);
|
||||||
|
|
||||||
/* Prompt for and read a login name */
|
/* Prompt for and read a login name */
|
||||||
G.line_buf[0] = '\0';
|
do {
|
||||||
while (!G.line_buf[0]) {
|
|
||||||
/* Write issue file and prompt */
|
/* Write issue file and prompt */
|
||||||
#ifdef ISSUE
|
#ifdef ISSUE
|
||||||
if (!(option_mask32 & F_NOISSUE))
|
if (!(option_mask32 & F_NOISSUE))
|
||||||
@ -458,9 +450,8 @@ static char *get_logname(void)
|
|||||||
#endif
|
#endif
|
||||||
print_login_prompt();
|
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;
|
bp = G.line_buf;
|
||||||
G.eol = '\0';
|
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Do not report trivial EINTR/EIO errors */
|
/* Do not report trivial EINTR/EIO errors */
|
||||||
errno = EINTR; /* make read of 0 bytes be silent too */
|
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);
|
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) {
|
switch (c) {
|
||||||
case '\r':
|
case '\r':
|
||||||
case '\n':
|
case '\n':
|
||||||
*bp = '\0';
|
*bp = '\0';
|
||||||
G.eol = c;
|
G.eol = c;
|
||||||
goto got_logname;
|
goto got_logname;
|
||||||
case BS:
|
case CTL('H'):
|
||||||
case DEL:
|
case 0x7f:
|
||||||
G.tty_attrs.c_cc[VERASE] = c;
|
G.tty_attrs.c_cc[VERASE] = c;
|
||||||
if (bp > G.line_buf) {
|
if (bp > G.line_buf) {
|
||||||
full_write(STDOUT_FILENO, "\010 \010", 3);
|
full_write(STDOUT_FILENO, "\010 \010", 3);
|
||||||
@ -497,9 +482,16 @@ static char *get_logname(void)
|
|||||||
bp--;
|
bp--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CTL('C'):
|
||||||
case CTL('D'):
|
case CTL('D'):
|
||||||
finalize_tty_attrs();
|
finalize_tty_attrs();
|
||||||
exit(EXIT_SUCCESS);
|
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:
|
default:
|
||||||
if ((unsigned char)c < ' ') {
|
if ((unsigned char)c < ' ') {
|
||||||
/* ignore garbage characters */
|
/* ignore garbage characters */
|
||||||
@ -512,7 +504,7 @@ static char *get_logname(void)
|
|||||||
}
|
}
|
||||||
} /* end of get char loop */
|
} /* end of get char loop */
|
||||||
got_logname: ;
|
got_logname: ;
|
||||||
} /* while logname is empty */
|
} while (G.line_buf[0] == '\0'); /* while logname is empty */
|
||||||
|
|
||||||
return G.line_buf;
|
return G.line_buf;
|
||||||
}
|
}
|
||||||
@ -682,9 +674,6 @@ int getty_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
|
|
||||||
finalize_tty_attrs();
|
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 */
|
/* Let the login program take care of password validation */
|
||||||
/* We use PATH because we trust that root doesn't set "bad" PATH,
|
/* We use PATH because we trust that root doesn't set "bad" PATH,
|
||||||
* and getty is not suid-root applet */
|
* 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)
|
if (pw->pw_uid != 0)
|
||||||
die_if_nologin();
|
die_if_nologin();
|
||||||
|
|
||||||
|
|
||||||
#if ENABLE_LOGIN_SESSION_AS_CHILD
|
#if ENABLE_LOGIN_SESSION_AS_CHILD
|
||||||
child_pid = vfork();
|
child_pid = vfork();
|
||||||
if (child_pid != 0) {
|
if (child_pid != 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user