Works like a champ. Good work Denys. Will this be part of the next busybox stable release (1.18.3) ?
Cheers rouble On Mon, Feb 7, 2011 at 11:08 PM, Denys Vlasenko <[email protected]> wrote: > On Tuesday 08 February 2011 04:13, Denys Vlasenko wrote: >> On Tuesday 08 February 2011 00:23, Harald Becker wrote: >> > >> > > Yes, 'reset' fixes the terminal. >> > > >> > > In Denys' fix, he closes STDIN when the inactivity timer pops. I >> > > wonder why that messes up the terminal? >> > Oh thats nothing to wonder about: The shell has to fiddle with the >> > terminal settings (raw/cooked) to allow line (advanced) editing. >> > Normally the terminal settings get saved and restored on shell exit ... >> > but if Denys closes stdio on alarm, that restore of the settings get >> > lost ... >> > >> > ... hey Denys, could you try to close only stdin on alarm and do the >> > terminal restore on stdout/stderr instead? ... just as a hint for a >> > possible solution. >> >> I plan to remove the hack of closing stdin and implement it properly >> in lineedit. > > Like this: > > diff -ad -urpN busybox.3/editors/ed.c busybox.4/editors/ed.c > --- busybox.3/editors/ed.c 2011-02-06 19:52:35.000000000 +0100 > +++ busybox.4/editors/ed.c 2011-02-08 04:41:44.000000000 +0100 > @@ -129,7 +129,7 @@ static void doCommands(void) > * 0 on ctrl-C, > * >0 length of input string, including terminating '\n' > */ > - len = read_line_input(": ", buf, sizeof(buf), NULL); > + len = read_line_input(NULL, ": ", buf, sizeof(buf), > /*timeout*/ -1); > if (len <= 0) > return; > endbuf = &buf[len - 1]; > @@ -227,7 +227,7 @@ static void doCommands(void) > } > if (!dirty) > return; > - len = read_line_input("Really quit? ", buf, 16, NULL); > + len = read_line_input(NULL, "Really quit? ", buf, 16, > /*timeout*/ -1); > /* read error/EOF - no way to continue */ > if (len < 0) > return; > @@ -541,7 +541,7 @@ static void addLines(int num) > * 0 on ctrl-C, > * >0 length of input string, including terminating '\n' > */ > - len = read_line_input("", buf, sizeof(buf), NULL); > + len = read_line_input(NULL, "", buf, sizeof(buf), /*timeout*/ > -1); > if (len <= 0) { > /* Previously, ctrl-C was exiting to shell. > * Now we exit to ed prompt. Is in important? */ > diff -ad -urpN busybox.3/include/libbb.h busybox.4/include/libbb.h > --- busybox.3/include/libbb.h 2011-02-08 04:16:08.000000000 +0100 > +++ busybox.4/include/libbb.h 2011-02-08 04:40:55.000000000 +0100 > @@ -1403,12 +1403,11 @@ line_input_t *new_line_input_t(int flags > * 0 on ctrl-C (the line entered is still returned in 'command'), > * >0 length of input string, including terminating '\n' > */ > -/* NB: ash has timeout code which can be moved into read_line_input, if > needed */ > -int read_line_input(const char* prompt, char* command, int maxsize, > line_input_t *state) FAST_FUNC; > +int read_line_input(line_input_t *st, const char *prompt, char *command, int > maxsize, int timeout) FAST_FUNC; > #else > #define MAX_HISTORY 0 > int read_line_input(const char* prompt, char* command, int maxsize) > FAST_FUNC; > -#define read_line_input(prompt, command, maxsize, state) \ > +#define read_line_input(state, prompt, command, maxsize, timeout) \ > read_line_input(prompt, command, maxsize) > #endif > > diff -ad -urpN busybox.3/libbb/lineedit.c busybox.4/libbb/lineedit.c > --- busybox.3/libbb/lineedit.c 2011-02-06 19:52:35.000000000 +0100 > +++ busybox.4/libbb/lineedit.c 2011-02-08 04:53:05.000000000 +0100 > @@ -1809,10 +1809,9 @@ static void win_changed(int nsig) > errno = sv_errno; > } > > -static int lineedit_read_key(char *read_key_buffer) > +static int lineedit_read_key(char *read_key_buffer, int timeout) > { > int64_t ic; > - int timeout = -1; > #if ENABLE_UNICODE_SUPPORT > char unicode_buf[MB_CUR_MAX + 1]; > int unicode_idx = 0; > @@ -1917,7 +1916,7 @@ static int isrtl_str(void) > * 0 on ctrl-C (the line entered is still returned in 'command'), > * >0 length of input string, including terminating '\n' > */ > -int FAST_FUNC read_line_input(const char *prompt, char *command, int > maxsize, line_input_t *st) > +int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char > *command, int maxsize, int timeout) > { > int len; > #if ENABLE_FEATURE_TAB_COMPLETION > @@ -1991,7 +1990,6 @@ int FAST_FUNC read_line_input(const char > new_settings.c_cc[VINTR] = _POSIX_VDISABLE; > tcsetattr_stdin_TCSANOW(&new_settings); > > - /* Now initialize things */ > previous_SIGWINCH_handler = signal(SIGWINCH, win_changed); > win_changed(0); /* do initial resizing */ > #if ENABLE_USERNAME_OR_HOMEDIR > @@ -2033,7 +2031,7 @@ int FAST_FUNC read_line_input(const char > int32_t ic, ic_raw; > > fflush_all(); > - ic = ic_raw = lineedit_read_key(read_key_buffer); > + ic = ic_raw = lineedit_read_key(read_key_buffer, timeout); > > #if ENABLE_FEATURE_EDITING_VI > newdelflag = 1; > @@ -2194,7 +2192,7 @@ int FAST_FUNC read_line_input(const char > case 'd'|VI_CMDMODE_BIT: { > int nc, sc; > > - ic = lineedit_read_key(read_key_buffer); > + ic = lineedit_read_key(read_key_buffer, timeout); > if (errno) /* error */ > goto return_error_indicator; > if (ic == ic_raw) { /* "cc", "dd" */ > @@ -2258,7 +2256,7 @@ int FAST_FUNC read_line_input(const char > break; > case 'r'|VI_CMDMODE_BIT: > //FIXME: unicode case? > - ic = lineedit_read_key(read_key_buffer); > + ic = lineedit_read_key(read_key_buffer, timeout); > if (errno) /* error */ > goto return_error_indicator; > if (ic < ' ' || ic > 255) { > diff -ad -urpN busybox.3/shell/ash.c busybox.4/shell/ash.c > --- busybox.3/shell/ash.c 2011-02-06 19:52:35.000000000 +0100 > +++ busybox.4/shell/ash.c 2011-02-08 05:01:28.000000000 +0100 > @@ -102,8 +102,7 @@ > //config: default n > //config: depends on ASH > //config: help > -//config: Enables bash-like auto-logout after "$TMOUT" seconds > -//config: of idle time. > +//config: Enables bash-like auto-logout after $TMOUT seconds of idle > time. > //config: > //config:config ASH_JOB_CONTROL > //config: bool "Job control" > @@ -408,6 +407,9 @@ static const char *var_end(const char *v > > > /* ============ Interrupts / exceptions */ > + > +static void exitshell(void) NORETURN; > + > /* > * These macros allow the user to suspend the handling of interrupt signals > * over a period of time. This is similar to SIGHOLD or to sigblock, but > @@ -9573,10 +9575,21 @@ preadfd(void) > if (!iflag || g_parsefile->pf_fd != STDIN_FILENO) > nr = nonblock_safe_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1); > else { > + int timeout = -1; > +# if ENABLE_ASH_IDLE_TIMEOUT > + if (iflag) { > + const char *tmout_var = lookupvar("TMOUT"); > + if (tmout_var) { > + timeout = atoi(tmout_var) * 1000; > + if (timeout <= 0) > + timeout = -1; > + } > + } > +# endif > # if ENABLE_FEATURE_TAB_COMPLETION > line_input_state->path_lookup = pathval(); > # endif > - nr = read_line_input(cmdedit_prompt, buf, IBUFSIZ, > line_input_state); > + nr = read_line_input(line_input_state, cmdedit_prompt, buf, > IBUFSIZ, timeout); > if (nr == 0) { > /* Ctrl+C pressed */ > if (trap[SIGINT]) { > @@ -9587,9 +9600,17 @@ preadfd(void) > } > goto retry; > } > - if (nr < 0 && errno == 0) { > - /* Ctrl+D pressed */ > - nr = 0; > + if (nr < 0) { > + if (errno == 0) { > + /* Ctrl+D pressed */ > + nr = 0; > + } > +# if ENABLE_ASH_IDLE_TIMEOUT > + else if (errno == EAGAIN && timeout > 0) { > + printf("\007timed out waiting for input: > auto-logout\n"); > + exitshell(); > + } > +# endif > } > } > #else > @@ -12056,23 +12077,6 @@ evalcmd(int argc UNUSED_PARAM, char **ar > return exitstatus; > } > > -#if ENABLE_ASH_IDLE_TIMEOUT > -static smallint timed_out; > - > -static void alrm_sighandler(int sig UNUSED_PARAM) > -{ > - /* Close stdin, making interactive command reading stop. > - * Otherwise, timeout doesn't trigger until <Enter> is pressed. > - */ > - int sv = errno; > - close(0); > - open("/dev/null", O_RDONLY); > - errno = sv; > - > - timed_out = 1; > -} > -#endif > - > /* > * Read and execute commands. > * "Top" is nonzero for the top level command loop; > @@ -12089,20 +12093,6 @@ cmdloop(int top) > TRACE(("cmdloop(%d) called\n", top)); > for (;;) { > int skip; > -#if ENABLE_ASH_IDLE_TIMEOUT > - int tmout_seconds = 0; > - > - if (top && iflag) { > - const char *tmout_var = lookupvar("TMOUT"); > - if (tmout_var) { > - tmout_seconds = atoi(tmout_var); > - if (tmout_seconds > 0) { > - signal(SIGALRM, alrm_sighandler); > - alarm(tmout_seconds); > - } > - } > - } > -#endif > > setstackmark(&smark); > #if JOBS > @@ -12115,14 +12105,6 @@ cmdloop(int top) > chkmail(); > } > n = parsecmd(inter); > -#if ENABLE_ASH_IDLE_TIMEOUT > - if (timed_out) { > - printf("\007timed out waiting for input: > auto-logout\n"); > - break; > - } > - if (tmout_seconds > 0) > - alarm(0); > -#endif > #if DEBUG > if (DEBUG > 2 && debug && (n != NODE_EOF)) > showtree(n); > @@ -12850,7 +12832,6 @@ ulimitcmd(int argc UNUSED_PARAM, char ** > /* > * Called to exit the shell. > */ > -static void exitshell(void) NORETURN; > static void > exitshell(void) > { > diff -ad -urpN busybox.3/shell/hush.c busybox.4/shell/hush.c > --- busybox.3/shell/hush.c 2011-02-07 02:02:44.000000000 +0100 > +++ busybox.4/shell/hush.c 2011-02-08 04:41:59.000000000 +0100 > @@ -1902,7 +1902,7 @@ static void get_user_input(struct in_str > G.flag_SIGINT = 0; > /* buglet: SIGINT will not make new prompt to appear _at once_, > * only after <Enter>. (^C will work) */ > - r = read_line_input(prompt_str, G.user_input_buf, > CONFIG_FEATURE_EDITING_MAX_LEN-1, G.line_input_state); > + r = read_line_input(G.line_input_state, prompt_str, > G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1, /*timeout*/ -1); > /* catch *SIGINT* etc (^C is handled by read_line_input) */ > check_and_run_traps(0); > } while (r == 0 || G.flag_SIGINT); /* repeat if ^C or SIGINT */ > diff -ad -urpN busybox.3/util-linux/fdisk.c busybox.4/util-linux/fdisk.c > --- busybox.3/util-linux/fdisk.c 2011-02-06 19:52:35.000000000 +0100 > +++ busybox.4/util-linux/fdisk.c 2011-02-08 04:41:18.000000000 +0100 > @@ -548,7 +548,7 @@ read_line(const char *prompt) > { > int sz; > > - sz = read_line_input(prompt, line_buffer, sizeof(line_buffer), NULL); > + sz = read_line_input(NULL, prompt, line_buffer, sizeof(line_buffer), > /*timeout*/ -1); > if (sz <= 0) > exit(EXIT_SUCCESS); /* Ctrl-D or Ctrl-C */ > > _______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
