aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-10-23 23:58:59 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-10-23 23:58:59 +0200
commite9dc354df86e9a3026de406520f6cd03a3519495 (patch)
treebe701340f824afa52536888ae116f96e02047967
parentee320c6d9cd0781233ed599d743b4da94b4424a7 (diff)
downloadbusybox-w32-e9dc354df86e9a3026de406520f6cd03a3519495.tar.gz
busybox-w32-e9dc354df86e9a3026de406520f6cd03a3519495.tar.bz2
busybox-w32-e9dc354df86e9a3026de406520f6cd03a3519495.zip
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>
-rw-r--r--loginutils/README70
-rw-r--r--loginutils/getty.c59
-rw-r--r--loginutils/login.c1
3 files changed, 94 insertions, 36 deletions
diff --git a/loginutils/README b/loginutils/README
new file mode 100644
index 000000000..ce8851097
--- /dev/null
+++ b/loginutils/README
@@ -0,0 +1,70 @@
1 Getty
2
3??? Should getty open tty with or without O_NONBLOCK?
4For serial lines, it means "should getty wait for Carrier Detect pin?"
5I checked other getties:
6
7- agetty always uses O_NONBLOCK
8- mgetty uses O_NONBLOCK unless run with -b, or as "getty"
9
10??? If we decided to use O_NONBLOCK (perhaps optionally with -b),
11when getty should send -I INITSTR data to tty? After open succeeds?
12What if we also want to initialize *modem* with some AT commands?
13
14??? Should we check/create /var/lock/LCK..ttyPFX lockfiles?
15
16??? mgetty opens tty but does NOT lock it, then waits for input via
17select/poll, and when input is available, it checks lock file.
18If it exists, mgetty exits (it assumes someone else uses the line).
19If no, it creates the file (lock the tty). Sounds like a good algorithm
20to use if we are called with -w...
21
22Getty should establish a new session and process group, and ensure
23that tty is a ctty.
24
25??? Should getty ensure that other processes which might have opened
26fds to this tty be dusconnected? agetty has a -R option which makes
27agetty call vhangup() after tty is opened. (Then agetty opens it again,
28since it probably vhangup'ed its own fd too).
29
30Getty should leave the tty in approximately the same state as "stty sane"
31before it execs login program. Minor things we do conditionally are:
32 c_iflag |= ICRNL; // if '\r' was used to end username
33
34??? mgetty uses per-tty file to ignore connects, /etc/nologin.ttyxx -
35is it useful?
36
37It should be possible to run "getty 0 -" from a shell prompt.
38[This currently doesn't work from interactive shell since setsid()
39fails in process group leader. The workaround is to run it as a child
40of something. sh -c 'getty - 0; true' usually works. Should we fix this?]
41It should leave tty in a sane state when it exits (Ctrl-D, -t SEC timeout):
42echo should be on, speed, control chars properly set, etc.
43(However, it can't restore ctty. The symptom is that "</dev/tty"
44fails in the parent shell after getty exits: /dev/tty can't be opened).
45
46Getty should write LOGIN_PROCESS utmp record before it starts waiting
47for username to be entered.
48
49 Login
50
51Login should not try to set up tty parameters - apart from switching echo
52off while entering password, and switching it back on after.
53
54Login should not leave "echo off" state when it times out reading password
55or otherwise terminates (Ctrl-C, Ctrl-D etc).
56
57??? Should login establish a new session and/or process group, and ensure
58that tty is a ctty? Without this, running login directly (not via getty)
59from e.g. initscript will usually result with a login session without
60ctty and without session/pgrp properly created...
61
62It should be possible to run "login [USER]" from a shell prompt,
63and it should work (not block/die/error out).
64Similarly to getty, it should leave tty in the sane state when it exits.
65
66??? Should login write LOGIN_PROCESS utmp record before it starts waiting
67for username/password to be entered?
68
69Login should write USER_PROCESS utmp record just before it is about
70to exec user's shell.
diff --git a/loginutils/getty.c b/loginutils/getty.c
index 32735642b..4d5219725 100644
--- a/loginutils/getty.c
+++ b/loginutils/getty.c
@@ -63,18 +63,8 @@ static FILE *dbf;
63 */ 63 */
64#define ISSUE "/etc/issue" 64#define ISSUE "/etc/issue"
65 65
66/* Some shorthands for control characters */ 66/* Macro to build Ctrl-LETTER. Assumes ASCII dialect */
67#define CTL(x) ((x) ^ 0100) /* Assumes ASCII dialect */ 67#define CTL(x) ((x) ^ 0100)
68#define BS CTL('H') /* back space */
69#define DEL CTL('?') /* delete */
70
71/* Defaults for line-editing etc. characters; you may want to change this */
72#define DEF_INTR CTL('C') /* default interrupt character */
73#define DEF_QUIT CTL('\\') /* default quit char */
74#define DEF_KILL CTL('U') /* default kill char */
75#define DEF_EOF CTL('D') /* default EOF char */
76#define DEF_EOL '\n'
77#define DEF_SWITCH 0 /* default switch char (none) */
78 68
79/* 69/*
80 * When multiple baud rates are specified on the command line, 70 * When multiple baud rates are specified on the command line,
@@ -365,17 +355,17 @@ static void finalize_tty_attrs(void)
365 * (why "stty sane" unsets this bit?) 355 * (why "stty sane" unsets this bit?)
366 */ 356 */
367 357
368 G.tty_attrs.c_cc[VINTR] = DEF_INTR; 358 G.tty_attrs.c_cc[VINTR] = CTL('C');
369 G.tty_attrs.c_cc[VQUIT] = DEF_QUIT; 359 G.tty_attrs.c_cc[VQUIT] = CTL('\\');
370 G.tty_attrs.c_cc[VEOF] = DEF_EOF; 360 G.tty_attrs.c_cc[VEOF] = CTL('D');
371 G.tty_attrs.c_cc[VEOL] = DEF_EOL; 361 G.tty_attrs.c_cc[VEOL] = '\n';
372#ifdef VSWTC 362#ifdef VSWTC
373 G.tty_attrs.c_cc[VSWTC] = DEF_SWITCH; 363 G.tty_attrs.c_cc[VSWTC] = 0;
374#endif 364#endif
375#ifdef VSWTCH 365#ifdef VSWTCH
376 G.tty_attrs.c_cc[VSWTCH] = DEF_SWITCH; 366 G.tty_attrs.c_cc[VSWTCH] = 0;
377#endif 367#endif
378 G.tty_attrs.c_cc[VKILL] = DEF_KILL; 368 G.tty_attrs.c_cc[VKILL] = CTL('U');
379 /* Other control chars: 369 /* Other control chars:
380 * VEOL2 370 * VEOL2
381 * VERASE, VWERASE - (word) erase. we may set VERASE in get_logname 371 * VERASE, VWERASE - (word) erase. we may set VERASE in get_logname
@@ -386,6 +376,9 @@ static void finalize_tty_attrs(void)
386 */ 376 */
387 377
388 set_tty_attrs(); 378 set_tty_attrs();
379
380 /* Now the newline character should be properly written */
381 full_write(STDOUT_FILENO, "\n", 1);
389} 382}
390 383
391/* extract baud rate from modem status message */ 384/* extract baud rate from modem status message */
@@ -449,8 +442,7 @@ static char *get_logname(void)
449 tcflush(STDIN_FILENO, TCIFLUSH); 442 tcflush(STDIN_FILENO, TCIFLUSH);
450 443
451 /* Prompt for and read a login name */ 444 /* Prompt for and read a login name */
452 G.line_buf[0] = '\0'; 445 do {
453 while (!G.line_buf[0]) {
454 /* Write issue file and prompt */ 446 /* Write issue file and prompt */
455#ifdef ISSUE 447#ifdef ISSUE
456 if (!(option_mask32 & F_NOISSUE)) 448 if (!(option_mask32 & F_NOISSUE))
@@ -458,9 +450,8 @@ static char *get_logname(void)
458#endif 450#endif
459 print_login_prompt(); 451 print_login_prompt();
460 452
461 /* Read name, watch for break, parity, erase, kill, end-of-line */ 453 /* Read name, watch for break, erase, kill, end-of-line */
462 bp = G.line_buf; 454 bp = G.line_buf;
463 G.eol = '\0';
464 while (1) { 455 while (1) {
465 /* Do not report trivial EINTR/EIO errors */ 456 /* Do not report trivial EINTR/EIO errors */
466 errno = EINTR; /* make read of 0 bytes be silent too */ 457 errno = EINTR; /* make read of 0 bytes be silent too */
@@ -471,20 +462,14 @@ static char *get_logname(void)
471 bb_perror_msg_and_die(bb_msg_read_error); 462 bb_perror_msg_and_die(bb_msg_read_error);
472 } 463 }
473 464
474 /* BREAK. If we have speeds to try,
475 * return NULL (will switch speeds and return here) */
476 if (c == '\0' && G.numspeed > 1)
477 return NULL;
478
479 /* Do erase, kill and end-of-line processing */
480 switch (c) { 465 switch (c) {
481 case '\r': 466 case '\r':
482 case '\n': 467 case '\n':
483 *bp = '\0'; 468 *bp = '\0';
484 G.eol = c; 469 G.eol = c;
485 goto got_logname; 470 goto got_logname;
486 case BS: 471 case CTL('H'):
487 case DEL: 472 case 0x7f:
488 G.tty_attrs.c_cc[VERASE] = c; 473 G.tty_attrs.c_cc[VERASE] = c;
489 if (bp > G.line_buf) { 474 if (bp > G.line_buf) {
490 full_write(STDOUT_FILENO, "\010 \010", 3); 475 full_write(STDOUT_FILENO, "\010 \010", 3);
@@ -497,9 +482,16 @@ static char *get_logname(void)
497 bp--; 482 bp--;
498 } 483 }
499 break; 484 break;
485 case CTL('C'):
500 case CTL('D'): 486 case CTL('D'):
501 finalize_tty_attrs(); 487 finalize_tty_attrs();
502 exit(EXIT_SUCCESS); 488 exit(EXIT_SUCCESS);
489 case '\0':
490 /* BREAK. If we have speeds to try,
491 * return NULL (will switch speeds and return here) */
492 if (G.numspeed > 1)
493 return NULL;
494 /* fall through and ignore it */
503 default: 495 default:
504 if ((unsigned char)c < ' ') { 496 if ((unsigned char)c < ' ') {
505 /* ignore garbage characters */ 497 /* ignore garbage characters */
@@ -512,7 +504,7 @@ static char *get_logname(void)
512 } 504 }
513 } /* end of get char loop */ 505 } /* end of get char loop */
514 got_logname: ; 506 got_logname: ;
515 } /* while logname is empty */ 507 } while (G.line_buf[0] == '\0'); /* while logname is empty */
516 508
517 return G.line_buf; 509 return G.line_buf;
518} 510}
@@ -682,9 +674,6 @@ int getty_main(int argc UNUSED_PARAM, char **argv)
682 674
683 finalize_tty_attrs(); 675 finalize_tty_attrs();
684 676
685 /* Now the newline character should be properly written */
686 full_write(STDOUT_FILENO, "\n", 1);
687
688 /* Let the login program take care of password validation */ 677 /* Let the login program take care of password validation */
689 /* We use PATH because we trust that root doesn't set "bad" PATH, 678 /* We use PATH because we trust that root doesn't set "bad" PATH,
690 * and getty is not suid-root applet */ 679 * and getty is not suid-root applet */
diff --git a/loginutils/login.c b/loginutils/login.c
index b54beef6e..73db8fa63 100644
--- a/loginutils/login.c
+++ b/loginutils/login.c
@@ -443,7 +443,6 @@ int login_main(int argc UNUSED_PARAM, char **argv)
443 if (pw->pw_uid != 0) 443 if (pw->pw_uid != 0)
444 die_if_nologin(); 444 die_if_nologin();
445 445
446
447#if ENABLE_LOGIN_SESSION_AS_CHILD 446#if ENABLE_LOGIN_SESSION_AS_CHILD
448 child_pid = vfork(); 447 child_pid = vfork();
449 if (child_pid != 0) { 448 if (child_pid != 0) {