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

Reply via email to