diff options
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 @@ //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 *var) /* ============ 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 **argv) 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 **argv) /* * Called to exit the shell. */ -static void exitshell(void) NORETURN; static void exitshell(void) { 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) 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 */ |