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 /shell | |
| 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>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/ash.c | 73 | ||||
| -rw-r--r-- | shell/hush.c | 2 |
2 files changed, 28 insertions, 47 deletions
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 */ |
