diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-02-08 05:07:02 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-02-08 05:07:02 +0100 |
commit | 66c5b12dbf85142eea257ba6047191d7c0ee43f3 (patch) | |
tree | 913ab2ca77d8a90bb48e75de12435d2776805da5 | |
parent | dd807c16f99b4ead544289b83c88cc2488542f72 (diff) | |
download | busybox-w32-66c5b12dbf85142eea257ba6047191d7c0ee43f3.tar.gz busybox-w32-66c5b12dbf85142eea257ba6047191d7c0ee43f3.tar.bz2 busybox-w32-66c5b12dbf85142eea257ba6047191d7c0ee43f3.zip |
ash: fix TMOUT not restoring tty attributes
function old new delta
pgetc 420 500 +80
readtoken1 3202 3239 +37
read_line_input 3316 3337 +21
udhcpc_main 2610 2630 +20
file_get 266 272 +6
expandarg 958 963 +5
localcmd 257 259 +2
addLines 85 87 +2
read_line 94 95 +1
ed_main 2540 2541 +1
timed_out 1 - -1
lineedit_read_key 256 255 -1
alrm_sighandler 44 - -44
cmdloop 539 434 -105
------------------------------------------------------------------------------
(add/remove: 0/2 grow/shrink: 10/2 up/down: 175/-151) Total: 24 bytes
text data bss dec hex filename
887379 936 17200 905515 dd12b busybox_old
887411 936 17192 905539 dd143 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/ed.c | 6 | ||||
-rw-r--r-- | include/libbb.h | 5 | ||||
-rw-r--r-- | libbb/lineedit.c | 12 | ||||
-rw-r--r-- | shell/ash.c | 73 | ||||
-rw-r--r-- | shell/hush.c | 2 | ||||
-rw-r--r-- | util-linux/fdisk.c | 2 |
6 files changed, 39 insertions, 61 deletions
diff --git a/editors/ed.c b/editors/ed.c index 859668406..b1b6a8d27 100644 --- a/editors/ed.c +++ b/editors/ed.c | |||
@@ -129,7 +129,7 @@ static void doCommands(void) | |||
129 | * 0 on ctrl-C, | 129 | * 0 on ctrl-C, |
130 | * >0 length of input string, including terminating '\n' | 130 | * >0 length of input string, including terminating '\n' |
131 | */ | 131 | */ |
132 | len = read_line_input(": ", buf, sizeof(buf), NULL); | 132 | len = read_line_input(NULL, ": ", buf, sizeof(buf), /*timeout*/ -1); |
133 | if (len <= 0) | 133 | if (len <= 0) |
134 | return; | 134 | return; |
135 | endbuf = &buf[len - 1]; | 135 | endbuf = &buf[len - 1]; |
@@ -227,7 +227,7 @@ static void doCommands(void) | |||
227 | } | 227 | } |
228 | if (!dirty) | 228 | if (!dirty) |
229 | return; | 229 | return; |
230 | len = read_line_input("Really quit? ", buf, 16, NULL); | 230 | len = read_line_input(NULL, "Really quit? ", buf, 16, /*timeout*/ -1); |
231 | /* read error/EOF - no way to continue */ | 231 | /* read error/EOF - no way to continue */ |
232 | if (len < 0) | 232 | if (len < 0) |
233 | return; | 233 | return; |
@@ -541,7 +541,7 @@ static void addLines(int num) | |||
541 | * 0 on ctrl-C, | 541 | * 0 on ctrl-C, |
542 | * >0 length of input string, including terminating '\n' | 542 | * >0 length of input string, including terminating '\n' |
543 | */ | 543 | */ |
544 | len = read_line_input("", buf, sizeof(buf), NULL); | 544 | len = read_line_input(NULL, "", buf, sizeof(buf), /*timeout*/ -1); |
545 | if (len <= 0) { | 545 | if (len <= 0) { |
546 | /* Previously, ctrl-C was exiting to shell. | 546 | /* Previously, ctrl-C was exiting to shell. |
547 | * Now we exit to ed prompt. Is in important? */ | 547 | * Now we exit to ed prompt. Is in important? */ |
diff --git a/include/libbb.h b/include/libbb.h index dd82e9754..78b390611 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1403,12 +1403,11 @@ line_input_t *new_line_input_t(int flags) FAST_FUNC; | |||
1403 | * 0 on ctrl-C (the line entered is still returned in 'command'), | 1403 | * 0 on ctrl-C (the line entered is still returned in 'command'), |
1404 | * >0 length of input string, including terminating '\n' | 1404 | * >0 length of input string, including terminating '\n' |
1405 | */ | 1405 | */ |
1406 | /* NB: ash has timeout code which can be moved into read_line_input, if needed */ | 1406 | int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) FAST_FUNC; |
1407 | int read_line_input(const char* prompt, char* command, int maxsize, line_input_t *state) FAST_FUNC; | ||
1408 | #else | 1407 | #else |
1409 | #define MAX_HISTORY 0 | 1408 | #define MAX_HISTORY 0 |
1410 | int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC; | 1409 | int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC; |
1411 | #define read_line_input(prompt, command, maxsize, state) \ | 1410 | #define read_line_input(state, prompt, command, maxsize, timeout) \ |
1412 | read_line_input(prompt, command, maxsize) | 1411 | read_line_input(prompt, command, maxsize) |
1413 | #endif | 1412 | #endif |
1414 | 1413 | ||
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 5dd835cca..afd28b75c 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -1809,10 +1809,9 @@ static void win_changed(int nsig) | |||
1809 | errno = sv_errno; | 1809 | errno = sv_errno; |
1810 | } | 1810 | } |
1811 | 1811 | ||
1812 | static int lineedit_read_key(char *read_key_buffer) | 1812 | static int lineedit_read_key(char *read_key_buffer, int timeout) |
1813 | { | 1813 | { |
1814 | int64_t ic; | 1814 | int64_t ic; |
1815 | int timeout = -1; | ||
1816 | #if ENABLE_UNICODE_SUPPORT | 1815 | #if ENABLE_UNICODE_SUPPORT |
1817 | char unicode_buf[MB_CUR_MAX + 1]; | 1816 | char unicode_buf[MB_CUR_MAX + 1]; |
1818 | int unicode_idx = 0; | 1817 | int unicode_idx = 0; |
@@ -1917,7 +1916,7 @@ static int isrtl_str(void) | |||
1917 | * 0 on ctrl-C (the line entered is still returned in 'command'), | 1916 | * 0 on ctrl-C (the line entered is still returned in 'command'), |
1918 | * >0 length of input string, including terminating '\n' | 1917 | * >0 length of input string, including terminating '\n' |
1919 | */ | 1918 | */ |
1920 | int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, line_input_t *st) | 1919 | int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) |
1921 | { | 1920 | { |
1922 | int len; | 1921 | int len; |
1923 | #if ENABLE_FEATURE_TAB_COMPLETION | 1922 | #if ENABLE_FEATURE_TAB_COMPLETION |
@@ -1991,7 +1990,6 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
1991 | new_settings.c_cc[VINTR] = _POSIX_VDISABLE; | 1990 | new_settings.c_cc[VINTR] = _POSIX_VDISABLE; |
1992 | tcsetattr_stdin_TCSANOW(&new_settings); | 1991 | tcsetattr_stdin_TCSANOW(&new_settings); |
1993 | 1992 | ||
1994 | /* Now initialize things */ | ||
1995 | previous_SIGWINCH_handler = signal(SIGWINCH, win_changed); | 1993 | previous_SIGWINCH_handler = signal(SIGWINCH, win_changed); |
1996 | win_changed(0); /* do initial resizing */ | 1994 | win_changed(0); /* do initial resizing */ |
1997 | #if ENABLE_USERNAME_OR_HOMEDIR | 1995 | #if ENABLE_USERNAME_OR_HOMEDIR |
@@ -2033,7 +2031,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
2033 | int32_t ic, ic_raw; | 2031 | int32_t ic, ic_raw; |
2034 | 2032 | ||
2035 | fflush_all(); | 2033 | fflush_all(); |
2036 | ic = ic_raw = lineedit_read_key(read_key_buffer); | 2034 | ic = ic_raw = lineedit_read_key(read_key_buffer, timeout); |
2037 | 2035 | ||
2038 | #if ENABLE_FEATURE_EDITING_VI | 2036 | #if ENABLE_FEATURE_EDITING_VI |
2039 | newdelflag = 1; | 2037 | newdelflag = 1; |
@@ -2194,7 +2192,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
2194 | case 'd'|VI_CMDMODE_BIT: { | 2192 | case 'd'|VI_CMDMODE_BIT: { |
2195 | int nc, sc; | 2193 | int nc, sc; |
2196 | 2194 | ||
2197 | ic = lineedit_read_key(read_key_buffer); | 2195 | ic = lineedit_read_key(read_key_buffer, timeout); |
2198 | if (errno) /* error */ | 2196 | if (errno) /* error */ |
2199 | goto return_error_indicator; | 2197 | goto return_error_indicator; |
2200 | if (ic == ic_raw) { /* "cc", "dd" */ | 2198 | if (ic == ic_raw) { /* "cc", "dd" */ |
@@ -2258,7 +2256,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li | |||
2258 | break; | 2256 | break; |
2259 | case 'r'|VI_CMDMODE_BIT: | 2257 | case 'r'|VI_CMDMODE_BIT: |
2260 | //FIXME: unicode case? | 2258 | //FIXME: unicode case? |
2261 | ic = lineedit_read_key(read_key_buffer); | 2259 | ic = lineedit_read_key(read_key_buffer, timeout); |
2262 | if (errno) /* error */ | 2260 | if (errno) /* error */ |
2263 | goto return_error_indicator; | 2261 | goto return_error_indicator; |
2264 | if (ic < ' ' || ic > 255) { | 2262 | if (ic < ' ' || ic > 255) { |
diff --git a/shell/ash.c b/shell/ash.c index bdc64790c..aaf21cd6f 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -102,8 +102,7 @@ | |||
102 | //config: default n | 102 | //config: default n |
103 | //config: depends on ASH | 103 | //config: depends on ASH |
104 | //config: help | 104 | //config: help |
105 | //config: Enables bash-like auto-logout after "$TMOUT" seconds | 105 | //config: Enables bash-like auto-logout after $TMOUT seconds of idle time. |
106 | //config: of idle time. | ||
107 | //config: | 106 | //config: |
108 | //config:config ASH_JOB_CONTROL | 107 | //config:config ASH_JOB_CONTROL |
109 | //config: bool "Job control" | 108 | //config: bool "Job control" |
@@ -408,6 +407,9 @@ static const char *var_end(const char *var) | |||
408 | 407 | ||
409 | 408 | ||
410 | /* ============ Interrupts / exceptions */ | 409 | /* ============ Interrupts / exceptions */ |
410 | |||
411 | static void exitshell(void) NORETURN; | ||
412 | |||
411 | /* | 413 | /* |
412 | * These macros allow the user to suspend the handling of interrupt signals | 414 | * These macros allow the user to suspend the handling of interrupt signals |
413 | * over a period of time. This is similar to SIGHOLD or to sigblock, but | 415 | * over a period of time. This is similar to SIGHOLD or to sigblock, but |
@@ -9573,10 +9575,21 @@ preadfd(void) | |||
9573 | if (!iflag || g_parsefile->pf_fd != STDIN_FILENO) | 9575 | if (!iflag || g_parsefile->pf_fd != STDIN_FILENO) |
9574 | nr = nonblock_safe_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1); | 9576 | nr = nonblock_safe_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1); |
9575 | else { | 9577 | else { |
9578 | int timeout = -1; | ||
9579 | # if ENABLE_ASH_IDLE_TIMEOUT | ||
9580 | if (iflag) { | ||
9581 | const char *tmout_var = lookupvar("TMOUT"); | ||
9582 | if (tmout_var) { | ||
9583 | timeout = atoi(tmout_var) * 1000; | ||
9584 | if (timeout <= 0) | ||
9585 | timeout = -1; | ||
9586 | } | ||
9587 | } | ||
9588 | # endif | ||
9576 | # if ENABLE_FEATURE_TAB_COMPLETION | 9589 | # if ENABLE_FEATURE_TAB_COMPLETION |
9577 | line_input_state->path_lookup = pathval(); | 9590 | line_input_state->path_lookup = pathval(); |
9578 | # endif | 9591 | # endif |
9579 | nr = read_line_input(cmdedit_prompt, buf, IBUFSIZ, line_input_state); | 9592 | nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ, timeout); |
9580 | if (nr == 0) { | 9593 | if (nr == 0) { |
9581 | /* Ctrl+C pressed */ | 9594 | /* Ctrl+C pressed */ |
9582 | if (trap[SIGINT]) { | 9595 | if (trap[SIGINT]) { |
@@ -9587,9 +9600,17 @@ preadfd(void) | |||
9587 | } | 9600 | } |
9588 | goto retry; | 9601 | goto retry; |
9589 | } | 9602 | } |
9590 | if (nr < 0 && errno == 0) { | 9603 | if (nr < 0) { |
9591 | /* Ctrl+D pressed */ | 9604 | if (errno == 0) { |
9592 | nr = 0; | 9605 | /* Ctrl+D pressed */ |
9606 | nr = 0; | ||
9607 | } | ||
9608 | # if ENABLE_ASH_IDLE_TIMEOUT | ||
9609 | else if (errno == EAGAIN && timeout > 0) { | ||
9610 | printf("\007timed out waiting for input: auto-logout\n"); | ||
9611 | exitshell(); | ||
9612 | } | ||
9613 | # endif | ||
9593 | } | 9614 | } |
9594 | } | 9615 | } |
9595 | #else | 9616 | #else |
@@ -12056,23 +12077,6 @@ evalcmd(int argc UNUSED_PARAM, char **argv) | |||
12056 | return exitstatus; | 12077 | return exitstatus; |
12057 | } | 12078 | } |
12058 | 12079 | ||
12059 | #if ENABLE_ASH_IDLE_TIMEOUT | ||
12060 | static smallint timed_out; | ||
12061 | |||
12062 | static void alrm_sighandler(int sig UNUSED_PARAM) | ||
12063 | { | ||
12064 | /* Close stdin, making interactive command reading stop. | ||
12065 | * Otherwise, timeout doesn't trigger until <Enter> is pressed. | ||
12066 | */ | ||
12067 | int sv = errno; | ||
12068 | close(0); | ||
12069 | open("/dev/null", O_RDONLY); | ||
12070 | errno = sv; | ||
12071 | |||
12072 | timed_out = 1; | ||
12073 | } | ||
12074 | #endif | ||
12075 | |||
12076 | /* | 12080 | /* |
12077 | * Read and execute commands. | 12081 | * Read and execute commands. |
12078 | * "Top" is nonzero for the top level command loop; | 12082 | * "Top" is nonzero for the top level command loop; |
@@ -12089,20 +12093,6 @@ cmdloop(int top) | |||
12089 | TRACE(("cmdloop(%d) called\n", top)); | 12093 | TRACE(("cmdloop(%d) called\n", top)); |
12090 | for (;;) { | 12094 | for (;;) { |
12091 | int skip; | 12095 | int skip; |
12092 | #if ENABLE_ASH_IDLE_TIMEOUT | ||
12093 | int tmout_seconds = 0; | ||
12094 | |||
12095 | if (top && iflag) { | ||
12096 | const char *tmout_var = lookupvar("TMOUT"); | ||
12097 | if (tmout_var) { | ||
12098 | tmout_seconds = atoi(tmout_var); | ||
12099 | if (tmout_seconds > 0) { | ||
12100 | signal(SIGALRM, alrm_sighandler); | ||
12101 | alarm(tmout_seconds); | ||
12102 | } | ||
12103 | } | ||
12104 | } | ||
12105 | #endif | ||
12106 | 12096 | ||
12107 | setstackmark(&smark); | 12097 | setstackmark(&smark); |
12108 | #if JOBS | 12098 | #if JOBS |
@@ -12115,14 +12105,6 @@ cmdloop(int top) | |||
12115 | chkmail(); | 12105 | chkmail(); |
12116 | } | 12106 | } |
12117 | n = parsecmd(inter); | 12107 | n = parsecmd(inter); |
12118 | #if ENABLE_ASH_IDLE_TIMEOUT | ||
12119 | if (timed_out) { | ||
12120 | printf("\007timed out waiting for input: auto-logout\n"); | ||
12121 | break; | ||
12122 | } | ||
12123 | if (tmout_seconds > 0) | ||
12124 | alarm(0); | ||
12125 | #endif | ||
12126 | #if DEBUG | 12108 | #if DEBUG |
12127 | if (DEBUG > 2 && debug && (n != NODE_EOF)) | 12109 | if (DEBUG > 2 && debug && (n != NODE_EOF)) |
12128 | showtree(n); | 12110 | showtree(n); |
@@ -12850,7 +12832,6 @@ ulimitcmd(int argc UNUSED_PARAM, char **argv) | |||
12850 | /* | 12832 | /* |
12851 | * Called to exit the shell. | 12833 | * Called to exit the shell. |
12852 | */ | 12834 | */ |
12853 | static void exitshell(void) NORETURN; | ||
12854 | static void | 12835 | static void |
12855 | exitshell(void) | 12836 | exitshell(void) |
12856 | { | 12837 | { |
diff --git a/shell/hush.c b/shell/hush.c index e857e7464..00ef361cd 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -1902,7 +1902,7 @@ static void get_user_input(struct in_str *i) | |||
1902 | G.flag_SIGINT = 0; | 1902 | G.flag_SIGINT = 0; |
1903 | /* buglet: SIGINT will not make new prompt to appear _at once_, | 1903 | /* buglet: SIGINT will not make new prompt to appear _at once_, |
1904 | * only after <Enter>. (^C will work) */ | 1904 | * only after <Enter>. (^C will work) */ |
1905 | r = read_line_input(prompt_str, G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1, G.line_input_state); | 1905 | r = read_line_input(G.line_input_state, prompt_str, G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1, /*timeout*/ -1); |
1906 | /* catch *SIGINT* etc (^C is handled by read_line_input) */ | 1906 | /* catch *SIGINT* etc (^C is handled by read_line_input) */ |
1907 | check_and_run_traps(0); | 1907 | check_and_run_traps(0); |
1908 | } while (r == 0 || G.flag_SIGINT); /* repeat if ^C or SIGINT */ | 1908 | } while (r == 0 || G.flag_SIGINT); /* repeat if ^C or SIGINT */ |
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index 02785ab85..0b93c22cc 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c | |||
@@ -548,7 +548,7 @@ read_line(const char *prompt) | |||
548 | { | 548 | { |
549 | int sz; | 549 | int sz; |
550 | 550 | ||
551 | sz = read_line_input(prompt, line_buffer, sizeof(line_buffer), NULL); | 551 | sz = read_line_input(NULL, prompt, line_buffer, sizeof(line_buffer), /*timeout*/ -1); |
552 | if (sz <= 0) | 552 | if (sz <= 0) |
553 | exit(EXIT_SUCCESS); /* Ctrl-D or Ctrl-C */ | 553 | exit(EXIT_SUCCESS); /* Ctrl-D or Ctrl-C */ |
554 | 554 | ||