Works like a champ. Good work Denys.
Post by Denys VlasenkoPost by Denys VlasenkoPost by Harald BeckerPost by roubleYes, '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.
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;
?//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 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 */