aboutsummaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c73
1 files changed, 27 insertions, 46 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 @@
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{