ash: fix TMOUT not restoring tty attributes

function                                             old     new   delta
pgetc                                                420     500     +80
readtoken1                                          3202    3239     +37
read_line_input                                     3316    3337     +21
udhcpc_main                                         2610    2630     +20
file_get                                             266     272      +6
expandarg                                            958     963      +5
localcmd                                             257     259      +2
addLines                                              85      87      +2
read_line                                             94      95      +1
ed_main                                             2540    2541      +1
timed_out                                              1       -      -1
lineedit_read_key                                    256     255      -1
alrm_sighandler                                       44       -     -44
cmdloop                                              539     434    -105
------------------------------------------------------------------------------
(add/remove: 0/2 grow/shrink: 10/2 up/down: 175/-151)          Total: 24 bytes
   text    data     bss     dec     hex filename
 887379     936   17200  905515   dd12b busybox_old
 887411     936   17192  905539   dd143 busybox_unstripped

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko
2011-02-08 05:07:02 +01:00
parent dd807c16f9
commit 66c5b12dbf
6 changed files with 39 additions and 61 deletions
+27 -46
View File
@@ -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)
{
+1 -1
View File
@@ -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 */