diff options
-rw-r--r-- | include/libbb.h | 4 | ||||
-rw-r--r-- | shell/ash.c | 47 |
2 files changed, 50 insertions, 1 deletions
diff --git a/include/libbb.h b/include/libbb.h index a0e23697c..6358e654a 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1393,12 +1393,14 @@ enum { }; line_input_t *new_line_input_t(int flags) FAST_FUNC; /* So far static: void free_line_input_t(line_input_t *n) FAST_FUNC; */ -/* maxsize must be >= 2. +/* + * maxsize must be >= 2. * Returns: * -1 on read errors or EOF, or on bare Ctrl-D, * 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; #else #define MAX_HISTORY 0 diff --git a/shell/ash.c b/shell/ash.c index 0e27a073c..bdc64790c 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -97,6 +97,14 @@ //config: help //config: Enable bash-compatible extensions. //config: +//config:config ASH_IDLE_TIMEOUT +//config: bool "Idle timeout variable" +//config: default n +//config: depends on ASH +//config: help +//config: Enables bash-like auto-logout after "$TMOUT" seconds +//config: of idle time. +//config: //config:config ASH_JOB_CONTROL //config: bool "Job control" //config: default y @@ -12048,6 +12056,23 @@ 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; @@ -12064,6 +12089,20 @@ 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 @@ -12076,6 +12115,14 @@ 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); |