aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-02-08 05:07:02 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2011-02-08 05:07:02 +0100
commit66c5b12dbf85142eea257ba6047191d7c0ee43f3 (patch)
tree913ab2ca77d8a90bb48e75de12435d2776805da5
parentdd807c16f99b4ead544289b83c88cc2488542f72 (diff)
downloadbusybox-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.c6
-rw-r--r--include/libbb.h5
-rw-r--r--libbb/lineedit.c12
-rw-r--r--shell/ash.c73
-rw-r--r--shell/hush.c2
-rw-r--r--util-linux/fdisk.c2
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 */ 1406int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) FAST_FUNC;
1407int 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
1410int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC; 1409int 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
1812static int lineedit_read_key(char *read_key_buffer) 1812static 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 */
1920int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, line_input_t *st) 1919int 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
411static 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
12060static smallint timed_out;
12061
12062static 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 */
12853static void exitshell(void) NORETURN;
12854static void 12835static void
12855exitshell(void) 12836exitshell(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