aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-11-07 01:52:10 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-11-07 01:52:10 +0000
commit6476cc108969cb44cad868d8df2c17ee2f953cc2 (patch)
tree2327b184cd989b3eff47e3b806457922b0f54365
parent9f60929cc4539fad039c7c89b0c60a34205a98e6 (diff)
downloadbusybox-w32-6476cc108969cb44cad868d8df2c17ee2f953cc2.tar.gz
busybox-w32-6476cc108969cb44cad868d8df2c17ee2f953cc2.tar.bz2
busybox-w32-6476cc108969cb44cad868d8df2c17ee2f953cc2.zip
getty: remove ancient termio support (was using termois anyway)
-rw-r--r--loginutils/getty.c166
1 files changed, 65 insertions, 101 deletions
diff --git a/loginutils/getty.c b/loginutils/getty.c
index e9b4f0755..0c269de98 100644
--- a/loginutils/getty.c
+++ b/loginutils/getty.c
@@ -19,48 +19,44 @@
19#include "busybox.h" 19#include "busybox.h"
20#include <syslog.h> 20#include <syslog.h>
21 21
22#ifdef CONFIG_FEATURE_UTMP 22#if ENABLE_FEATURE_UTMP
23#include <utmp.h> 23#include <utmp.h>
24#endif 24#endif
25 25
26 /* 26/*
27 * Some heuristics to find out what environment we are in: if it is not 27 * Some heuristics to find out what environment we are in: if it is not
28 * System V, assume it is SunOS 4. 28 * System V, assume it is SunOS 4.
29 */ 29 */
30
31#ifdef LOGIN_PROCESS /* defined in System V utmp.h */ 30#ifdef LOGIN_PROCESS /* defined in System V utmp.h */
32#define SYSV_STYLE /* select System V style getty */ 31#define SYSV_STYLE /* select System V style getty */
33#ifdef CONFIG_FEATURE_WTMP
34extern void updwtmp(const char *filename, const struct utmp *ut);
35#endif
36#endif /* LOGIN_PROCESS */
37
38#ifdef SYSV_STYLE
39#include <sys/utsname.h> 32#include <sys/utsname.h>
40#include <time.h> 33#include <time.h>
34#if ENABLE_FEATURE_WTMP
35extern void updwtmp(const char *filename, const struct utmp *ut);
36static void update_utmp(char *line);
41#endif 37#endif
38#endif /* LOGIN_PROCESS */
42 39
43 /* 40/*
44 * Things you may want to modify. 41 * Things you may want to modify.
45 * 42 *
46 * You may disagree with the default line-editing etc. characters defined 43 * You may disagree with the default line-editing etc. characters defined
47 * below. Note, however, that DEL cannot be used for interrupt generation 44 * below. Note, however, that DEL cannot be used for interrupt generation
48 * and for line editing at the same time. 45 * and for line editing at the same time.
49 */ 46 */
50 47
51/* I doubt there are systems which still need this */ 48/* I doubt there are systems which still need this */
52#undef HANDLE_ALLCAPS 49#undef HANDLE_ALLCAPS
53 50
54#define _PATH_LOGIN "/bin/login" 51#define _PATH_LOGIN "/bin/login"
55 52
56 /* If ISSUE is not defined, agetty will never display the contents of the 53/* If ISSUE is not defined, getty will never display the contents of the
57 * /etc/issue file. You will not want to spit out large "issue" files at the 54 * /etc/issue file. You will not want to spit out large "issue" files at the
58 * wrong baud rate. 55 * wrong baud rate.
59 */ 56 */
60#define ISSUE "/etc/issue" /* displayed before the login prompt */ 57#define ISSUE "/etc/issue" /* displayed before the login prompt */
61 58
62/* Some shorthands for control characters. */ 59/* Some shorthands for control characters. */
63
64#define CTL(x) (x ^ 0100) /* Assumes ASCII dialect */ 60#define CTL(x) (x ^ 0100) /* Assumes ASCII dialect */
65#define CR CTL('M') /* carriage return */ 61#define CR CTL('M') /* carriage return */
66#define NL CTL('J') /* line feed */ 62#define NL CTL('J') /* line feed */
@@ -68,7 +64,6 @@ extern void updwtmp(const char *filename, const struct utmp *ut);
68#define DEL CTL('?') /* delete */ 64#define DEL CTL('?') /* delete */
69 65
70/* Defaults for line-editing etc. characters; you may want to change this. */ 66/* Defaults for line-editing etc. characters; you may want to change this. */
71
72#define DEF_ERASE DEL /* default erase character */ 67#define DEF_ERASE DEL /* default erase character */
73#define DEF_INTR CTL('C') /* default interrupt character */ 68#define DEF_INTR CTL('C') /* default interrupt character */
74#define DEF_QUIT CTL('\\') /* default quit char */ 69#define DEF_QUIT CTL('\\') /* default quit char */
@@ -77,32 +72,10 @@ extern void updwtmp(const char *filename, const struct utmp *ut);
77#define DEF_EOL '\n' 72#define DEF_EOL '\n'
78#define DEF_SWITCH 0 /* default switch char */ 73#define DEF_SWITCH 0 /* default switch char */
79 74
80 /* 75/*
81 * SunOS 4.1.1 termio is broken. We must use the termios stuff instead, 76 * When multiple baud rates are specified on the command line, the first one
82 * because the termio -> termios translation does not clear the termios 77 * we will try is the first one specified.
83 * CIBAUD bits. Therefore, the tty driver would sometimes report that input 78 */
84 * baud rate != output baud rate. I did not notice that problem with SunOS
85 * 4.1. We will use termios where available, and termio otherwise.
86 */
87
88/* linux 0.12 termio is broken too, if we use it c_cc[VERASE] isn't set
89 properly, but all is well if we use termios?! */
90
91#ifdef TCGETS
92#undef TCGETA
93#undef TCSETA
94#undef TCSETAW
95#define termio termios
96#define TCGETA TCGETS
97#define TCSETA TCSETS
98#define TCSETAW TCSETSW
99#endif
100
101 /*
102 * When multiple baud rates are specified on the command line, the first one
103 * we will try is the first one specified.
104 */
105
106#define FIRST_SPEED 0 79#define FIRST_SPEED 0
107 80
108/* Storage for command-line options. */ 81/* Storage for command-line options. */
@@ -134,7 +107,6 @@ static const char opt_string[] = "I:LH:f:hil:mt:wn";
134#define F_NOPROMPT (1<<10) /* don't ask for login name! */ 107#define F_NOPROMPT (1<<10) /* don't ask for login name! */
135 108
136/* Storage for things detected while the login name was read. */ 109/* Storage for things detected while the login name was read. */
137
138struct chardata { 110struct chardata {
139 unsigned char erase; /* erase character */ 111 unsigned char erase; /* erase character */
140 unsigned char kill; /* kill character */ 112 unsigned char kill; /* kill character */
@@ -146,7 +118,6 @@ struct chardata {
146}; 118};
147 119
148/* Initial values for the above. */ 120/* Initial values for the above. */
149
150static const struct chardata init_chardata = { 121static const struct chardata init_chardata = {
151 DEF_ERASE, /* default erase character */ 122 DEF_ERASE, /* default erase character */
152 DEF_KILL, /* default kill character */ 123 DEF_KILL, /* default kill character */
@@ -157,12 +128,6 @@ static const struct chardata init_chardata = {
157#endif 128#endif
158}; 129};
159 130
160#ifdef SYSV_STYLE
161#ifdef CONFIG_FEATURE_UTMP
162static void update_utmp(char *line);
163#endif
164#endif
165
166/* The following is used for understandable diagnostics. */ 131/* The following is used for understandable diagnostics. */
167 132
168/* Fake hostname for ut_host specified on command line. */ 133/* Fake hostname for ut_host specified on command line. */
@@ -268,7 +233,7 @@ static void xdup2(int srcfd, int dstfd, const char *tty)
268} 233}
269 234
270/* open_tty - set up tty as standard { input, output, error } */ 235/* open_tty - set up tty as standard { input, output, error } */
271static void open_tty(char *tty, struct termio *tp, int local) 236static void open_tty(char *tty, struct termios *tp, int local)
272{ 237{
273 int chdir_to_root = 0; 238 int chdir_to_root = 0;
274 239
@@ -318,8 +283,8 @@ static void open_tty(char *tty, struct termio *tp, int local)
318 * 5 seconds seems to be a good value. 283 * 5 seconds seems to be a good value.
319 */ 284 */
320 285
321 if (ioctl(0, TCGETA, tp) < 0) 286 if (ioctl(0, TCGETS, tp) < 0)
322 bb_perror_msg_and_die("%s: ioctl(TCGETA)", tty); 287 bb_perror_msg_and_die("%s: ioctl(TCGETS)", tty);
323 288
324 /* 289 /*
325 * It seems to be a terminal. Set proper protections and ownership. Mode 290 * It seems to be a terminal. Set proper protections and ownership. Mode
@@ -369,11 +334,11 @@ static void open_tty(char *tty, struct termio *tp, int local)
369 xchdir("/"); 334 xchdir("/");
370} 335}
371 336
372/* termio_init - initialize termio settings */ 337/* termios_init - initialize termios settings */
373static void termio_init(struct termio *tp, int speed, struct options *op) 338static void termios_init(struct termios *tp, int speed, struct options *op)
374{ 339{
375 /* 340 /*
376 * Initial termio settings: 8-bit characters, raw-mode, blocking i/o. 341 * Initial termios settings: 8-bit characters, raw-mode, blocking i/o.
377 * Special characters are set after we have read the login name; all 342 * Special characters are set after we have read the login name; all
378 * reads will be done in raw mode anyway. Errors will be dealt with 343 * reads will be done in raw mode anyway. Errors will be dealt with
379 * later on. 344 * later on.
@@ -400,7 +365,7 @@ static void termio_init(struct termio *tp, int speed, struct options *op)
400 tp->c_cflag |= CRTSCTS; 365 tp->c_cflag |= CRTSCTS;
401#endif 366#endif
402 367
403 ioctl(0, TCSETA, tp); 368 ioctl(0, TCSETS, tp);
404 369
405 /* go to blocking input even in local mode */ 370 /* go to blocking input even in local mode */
406 fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) & ~O_NONBLOCK); 371 fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) & ~O_NONBLOCK);
@@ -409,7 +374,7 @@ static void termio_init(struct termio *tp, int speed, struct options *op)
409} 374}
410 375
411/* auto_baud - extract baud rate from modem status message */ 376/* auto_baud - extract baud rate from modem status message */
412static void auto_baud(char *buf, unsigned size_buf, struct termio *tp) 377static void auto_baud(char *buf, unsigned size_buf, struct termios *tp)
413{ 378{
414 int speed; 379 int speed;
415 int vmin; 380 int vmin;
@@ -441,7 +406,7 @@ static void auto_baud(char *buf, unsigned size_buf, struct termio *tp)
441 tp->c_iflag |= ISTRIP; /* enable 8th-bit stripping */ 406 tp->c_iflag |= ISTRIP; /* enable 8th-bit stripping */
442 vmin = tp->c_cc[VMIN]; 407 vmin = tp->c_cc[VMIN];
443 tp->c_cc[VMIN] = 0; /* don't block if queue empty */ 408 tp->c_cc[VMIN] = 0; /* don't block if queue empty */
444 ioctl(0, TCSETA, tp); 409 ioctl(0, TCSETS, tp);
445 410
446 /* 411 /*
447 * Wait for a while, then read everything the modem has said so far and 412 * Wait for a while, then read everything the modem has said so far and
@@ -467,23 +432,23 @@ static void auto_baud(char *buf, unsigned size_buf, struct termio *tp)
467 432
468 tp->c_iflag = iflag; 433 tp->c_iflag = iflag;
469 tp->c_cc[VMIN] = vmin; 434 tp->c_cc[VMIN] = vmin;
470 ioctl(0, TCSETA, tp); 435 ioctl(0, TCSETS, tp);
471} 436}
472 437
473/* next_speed - select next baud rate */ 438/* next_speed - select next baud rate */
474static void next_speed(struct termio *tp, struct options *op) 439static void next_speed(struct termios *tp, struct options *op)
475{ 440{
476 static int baud_index = FIRST_SPEED; /* current speed index */ 441 static int baud_index = FIRST_SPEED; /* current speed index */
477 442
478 baud_index = (baud_index + 1) % op->numspeed; 443 baud_index = (baud_index + 1) % op->numspeed;
479 tp->c_cflag &= ~CBAUD; 444 tp->c_cflag &= ~CBAUD;
480 tp->c_cflag |= op->speeds[baud_index]; 445 tp->c_cflag |= op->speeds[baud_index];
481 ioctl(0, TCSETA, tp); 446 ioctl(0, TCSETS, tp);
482} 447}
483 448
484 449
485/* do_prompt - show login prompt, optionally preceded by /etc/issue contents */ 450/* do_prompt - show login prompt, optionally preceded by /etc/issue contents */
486static void do_prompt(struct options *op, struct termio *tp) 451static void do_prompt(struct options *op, struct termios *tp)
487{ 452{
488#ifdef ISSUE 453#ifdef ISSUE
489 print_login_issue(op->issue, op->tty); 454 print_login_issue(op->issue, op->tty);
@@ -506,7 +471,7 @@ static int caps_lock(const char *s)
506/* get_logname - get user name, establish parity, speed, erase, kill, eol */ 471/* get_logname - get user name, establish parity, speed, erase, kill, eol */
507/* return NULL on failure, logname on success */ 472/* return NULL on failure, logname on success */
508static char *get_logname(char *logname, unsigned size_logname, 473static char *get_logname(char *logname, unsigned size_logname,
509 struct options *op, struct chardata *cp, struct termio *tp) 474 struct options *op, struct chardata *cp, struct termios *tp)
510{ 475{
511 char *bp; 476 char *bp;
512 char c; /* input character, full eight bits */ 477 char c; /* input character, full eight bits */
@@ -621,8 +586,8 @@ static char *get_logname(char *logname, unsigned size_logname,
621 return logname; 586 return logname;
622} 587}
623 588
624/* termio_final - set the final tty mode bits */ 589/* termios_final - set the final tty mode bits */
625static void termio_final(struct options *op, struct termio *tp, struct chardata *cp) 590static void termios_final(struct options *op, struct termios *tp, struct chardata *cp)
626{ 591{
627 /* General terminal-independent stuff. */ 592 /* General terminal-independent stuff. */
628 593
@@ -681,13 +646,13 @@ static void termio_final(struct options *op, struct termio *tp, struct chardata
681 646
682 /* Finally, make the new settings effective */ 647 /* Finally, make the new settings effective */
683 648
684 if (ioctl(0, TCSETA, tp) < 0) 649 if (ioctl(0, TCSETS, tp) < 0)
685 bb_perror_msg_and_die("%s: ioctl(TCSETA)", op->tty); 650 bb_perror_msg_and_die("%s: ioctl(TCSETS)", op->tty);
686} 651}
687 652
688 653
689#ifdef SYSV_STYLE 654#ifdef SYSV_STYLE
690#ifdef CONFIG_FEATURE_UTMP 655#if ENABLE_FEATURE_UTMP
691/* update_utmp - update our utmp entry */ 656/* update_utmp - update our utmp entry */
692static void update_utmp(char *line) 657static void update_utmp(char *line)
693{ 658{
@@ -695,9 +660,6 @@ static void update_utmp(char *line)
695 struct utmp *utp; 660 struct utmp *utp;
696 time_t t; 661 time_t t;
697 int mypid = getpid(); 662 int mypid = getpid();
698#if ! (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1))
699 struct flock lock;
700#endif
701 663
702 /* 664 /*
703 * The utmp file holds miscellaneous information about things started by 665 * The utmp file holds miscellaneous information about things started by
@@ -737,7 +699,7 @@ static void update_utmp(char *line)
737 pututline(&ut); 699 pututline(&ut);
738 endutent(); 700 endutent();
739 701
740#ifdef CONFIG_FEATURE_WTMP 702#if ENABLE_FEATURE_WTMP
741 if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) 703 if (access(bb_path_wtmp_file, R_OK|W_OK) == -1)
742 close(creat(bb_path_wtmp_file, 0664)); 704 close(creat(bb_path_wtmp_file, 0664));
743 updwtmp(bb_path_wtmp_file, &ut); 705 updwtmp(bb_path_wtmp_file, &ut);
@@ -752,10 +714,11 @@ int getty_main(int argc, char **argv)
752{ 714{
753 int nullfd; 715 int nullfd;
754 char *logname = NULL; /* login name, given to /bin/login */ 716 char *logname = NULL; /* login name, given to /bin/login */
755 // TODO: we can merge these into "struct local" 717 /* Merging these into "struct local" may _seem_ to reduce
756 // (will reduce parameter passing) 718 * parameter passing, but today's gcc will inline
719 * statics which are called once anyway, so don't do that */
757 struct chardata chardata; /* set by get_logname() */ 720 struct chardata chardata; /* set by get_logname() */
758 struct termio termio; /* terminal mode bits */ 721 struct termios termios; /* terminal mode bits */
759 struct options options = { 722 struct options options = {
760 0, /* show /etc/issue (SYSV_STYLE) */ 723 0, /* show /etc/issue (SYSV_STYLE) */
761 0, /* no timeout */ 724 0, /* no timeout */
@@ -783,11 +746,12 @@ int getty_main(int argc, char **argv)
783 /* Was "/dev/console". Why should we spam *system console* 746 /* Was "/dev/console". Why should we spam *system console*
784 * if there is a problem with getty on /dev/ttyS15?... */ 747 * if there is a problem with getty on /dev/ttyS15?... */
785 nullfd = xopen(bb_dev_null, O_RDWR); 748 nullfd = xopen(bb_dev_null, O_RDWR);
786 dup2(nullfd, 0); 749 if (nullfd) {
787 dup2(nullfd, 1); 750 dup2(nullfd, 0);
788 dup2(nullfd, 2);
789 if (nullfd > 2)
790 close(nullfd); 751 close(nullfd);
752 }
753 dup2(0, 1);
754 dup2(0, 2);
791 /* We want special flavor of error_msg_and_die */ 755 /* We want special flavor of error_msg_and_die */
792 die_sleep = 10; 756 die_sleep = 10;
793 msg_eol = "\r\n"; 757 msg_eol = "\r\n";
@@ -811,7 +775,7 @@ int getty_main(int argc, char **argv)
811 parse_args(argc, argv, &options); 775 parse_args(argc, argv, &options);
812 776
813#ifdef SYSV_STYLE 777#ifdef SYSV_STYLE
814#ifdef CONFIG_FEATURE_UTMP 778#if ENABLE_FEATURE_UTMP
815 /* Update the utmp file. */ 779 /* Update the utmp file. */
816 update_utmp(options.tty); 780 update_utmp(options.tty);
817#endif 781#endif
@@ -819,7 +783,7 @@ int getty_main(int argc, char **argv)
819 783
820 debug("calling open_tty\n"); 784 debug("calling open_tty\n");
821 /* Open the tty as standard { input, output, error }. */ 785 /* Open the tty as standard { input, output, error }. */
822 open_tty(options.tty, &termio, options.flags & F_LOCAL); 786 open_tty(options.tty, &termios, options.flags & F_LOCAL);
823 787
824#ifdef __linux__ 788#ifdef __linux__
825 { 789 {
@@ -829,9 +793,9 @@ int getty_main(int argc, char **argv)
829 ioctl(0, TIOCSPGRP, &iv); 793 ioctl(0, TIOCSPGRP, &iv);
830 } 794 }
831#endif 795#endif
832 /* Initialize the termio settings (raw mode, eight-bit, blocking i/o). */ 796 /* Initialize the termios settings (raw mode, eight-bit, blocking i/o). */
833 debug("calling termio_init\n"); 797 debug("calling termios_init\n");
834 termio_init(&termio, options.speeds[FIRST_SPEED], &options); 798 termios_init(&termios, options.speeds[FIRST_SPEED], &options);
835 799
836 /* write the modem init string and DON'T flush the buffers */ 800 /* write the modem init string and DON'T flush the buffers */
837 if (options.flags & F_INITSTRING) { 801 if (options.flags & F_INITSTRING) {
@@ -847,7 +811,7 @@ int getty_main(int argc, char **argv)
847 /* Optionally detect the baud rate from the modem status message. */ 811 /* Optionally detect the baud rate from the modem status message. */
848 debug("before autobaud\n"); 812 debug("before autobaud\n");
849 if (options.flags & F_PARSE) 813 if (options.flags & F_PARSE)
850 auto_baud(bb_common_bufsiz1, sizeof(bb_common_bufsiz1), &termio); 814 auto_baud(bb_common_bufsiz1, sizeof(bb_common_bufsiz1), &termios);
851 815
852 /* Set the optional timer. */ 816 /* Set the optional timer. */
853 if (options.timeout) 817 if (options.timeout)
@@ -873,9 +837,9 @@ int getty_main(int argc, char **argv)
873 /* Read the login name. */ 837 /* Read the login name. */
874 debug("reading login name\n"); 838 debug("reading login name\n");
875 logname = get_logname(bb_common_bufsiz1, sizeof(bb_common_bufsiz1), 839 logname = get_logname(bb_common_bufsiz1, sizeof(bb_common_bufsiz1),
876 &options, &chardata, &termio); 840 &options, &chardata, &termios);
877 while (logname == NULL) 841 while (logname == NULL)
878 next_speed(&termio, &options); 842 next_speed(&termios, &options);
879 } 843 }
880 844
881 /* Disable timer. */ 845 /* Disable timer. */
@@ -883,9 +847,9 @@ int getty_main(int argc, char **argv)
883 if (options.timeout) 847 if (options.timeout)
884 alarm(0); 848 alarm(0);
885 849
886 /* Finalize the termio settings. */ 850 /* Finalize the termios settings. */
887 851
888 termio_final(&options, &termio, &chardata); 852 termios_final(&options, &termios, &chardata);
889 853
890 /* Now the newline character should be properly written. */ 854 /* Now the newline character should be properly written. */
891 855