diff --git a/editors/ed.c b/editors/ed.c index 7f21ded92..05797692c 100644 --- a/editors/ed.c +++ b/editors/ed.c @@ -360,7 +360,7 @@ static void addLines(int num) * 0 on ctrl-C, * >0 length of input string, including terminating '\n' */ - len = read_line_input(NULL, "", buf, sizeof(buf), /*timeout*/ -1); + len = read_line_input(NULL, "", buf, sizeof(buf)); if (len <= 0) { /* Previously, ctrl-C was exiting to shell. * Now we exit to ed prompt. Is in important? */ @@ -789,7 +789,7 @@ static void doCommands(void) * 0 on ctrl-C, * >0 length of input string, including terminating '\n' */ - len = read_line_input(NULL, ": ", buf, sizeof(buf), /*timeout*/ -1); + len = read_line_input(NULL, ": ", buf, sizeof(buf)); if (len <= 0) return; while (len && isspace(buf[--len])) @@ -892,7 +892,7 @@ static void doCommands(void) } if (!dirty) return; - len = read_line_input(NULL, "Really quit? ", buf, 16, /*timeout*/ -1); + len = read_line_input(NULL, "Really quit? ", buf, 16); /* read error/EOF - no way to continue */ if (len < 0) return; diff --git a/include/libbb.h b/include/libbb.h index 9aba71949..46180c5aa 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1639,9 +1639,9 @@ enum { * buffer[0] is used as a counter of buffered chars and must be 0 * on first call. * timeout: - * -2: do not poll for input; - * -1: poll(-1) (i.e. block); - * >=0: poll for TIMEOUT milliseconds, return -1/EAGAIN on timeout + * -2: do not poll(-1) for input - read() it, return on EAGAIN at once + * -1: poll(-1) (i.e. block even on NONBLOCKed fd) + * >=0: poll() for TIMEOUT milliseconds, return -1/EAGAIN on timeout */ int64_t read_key(int fd, char *buffer, int timeout) FAST_FUNC; void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC; @@ -1657,6 +1657,7 @@ unsigned size_from_HISTFILESIZE(const char *hp) FAST_FUNC; # endif typedef struct line_input_t { int flags; + int timeout; const char *path_lookup; # if MAX_HISTORY int cnt_history; @@ -1692,7 +1693,7 @@ line_input_t *new_line_input_t(int flags) FAST_FUNC; * 0 on ctrl-C (the line entered is still returned in 'command'), * >0 length of input string, including terminating '\n' */ -int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) FAST_FUNC; +int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize) FAST_FUNC; void show_history(const line_input_t *st) FAST_FUNC; # if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT void save_history(line_input_t *st); @@ -1700,7 +1701,7 @@ void save_history(line_input_t *st); #else #define MAX_HISTORY 0 int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC; -#define read_line_input(state, prompt, command, maxsize, timeout) \ +#define read_line_input(state, prompt, command, maxsize) \ read_line_input(prompt, command, maxsize) #endif diff --git a/libbb/lineedit.c b/libbb/lineedit.c index e5721b063..0106093a1 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -1267,6 +1267,7 @@ line_input_t* FAST_FUNC new_line_input_t(int flags) { line_input_t *n = xzalloc(sizeof(*n)); n->flags = flags; + n->timeout = -1; #if MAX_HISTORY > 0 n->max_history = MAX_HISTORY; #endif @@ -2130,7 +2131,7 @@ enum { * Backspace deletes last matched char. * Control keys exit search and return to normal editing (at current history line). */ -static int32_t reverse_i_search(void) +static int32_t reverse_i_search(int timeout) { char match_buf[128]; /* for user input */ char read_key_buffer[KEYCODE_BUFFER_SIZE]; @@ -2152,8 +2153,8 @@ static int32_t reverse_i_search(void) int h; unsigned match_buf_len = strlen(match_buf); -//FIXME: correct timeout? - ic = lineedit_read_key(read_key_buffer, -1); +//FIXME: correct timeout? (i.e. count it down?) + ic = lineedit_read_key(read_key_buffer, timeout); switch (ic) { case CTRL('R'): /* searching for the next match */ @@ -2256,9 +2257,10 @@ static int32_t reverse_i_search(void) * (in both cases the cursor remains on the input line, '\n' is not printed) * >0 length of input string, including terminating '\n' */ -int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) +int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize) { int len; + int timeout; #if ENABLE_FEATURE_TAB_COMPLETION smallint lastWasTab = 0; #endif @@ -2297,8 +2299,15 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman maxsize = MAX_LINELEN; S.maxsize = maxsize; - /* With zero flags, no other fields are ever used */ - state = st ? st : (line_input_t*) &const_int_0; + timeout = -1; + /* Make state->flags == 0 if st is NULL. + * With zeroed flags, no other fields are ever referenced. + */ + state = (line_input_t*) &const_int_0; + if (st) { + state = st; + timeout = st->timeout; + } #if MAX_HISTORY > 0 # if ENABLE_FEATURE_EDITING_SAVEHISTORY if (state->hist_file) @@ -2510,7 +2519,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman } #if ENABLE_FEATURE_REVERSE_SEARCH case CTRL('R'): - ic = ic_raw = reverse_i_search(); + ic = ic_raw = reverse_i_search(timeout); goto again; #endif diff --git a/shell/ash.c b/shell/ash.c index 78baa9aac..b285e3d33 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -10185,8 +10185,8 @@ preadfd(void) if (!iflag || g_parsefile->pf_fd != STDIN_FILENO) nr = nonblock_immune_read(g_parsefile->pf_fd, buf, IBUFSIZ - 1); else { - int timeout = -1; # if ENABLE_ASH_IDLE_TIMEOUT + int timeout = -1; if (iflag) { const char *tmout_var = lookupvar("TMOUT"); if (tmout_var) { @@ -10195,12 +10195,13 @@ preadfd(void) timeout = -1; } } + line_input_state->timeout = timeout; # endif # if ENABLE_FEATURE_TAB_COMPLETION line_input_state->path_lookup = pathval(); # endif reinit_unicode_for_ash(); - nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ, timeout); + nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ); if (nr == 0) { /* ^C pressed, "convert" to SIGINT */ write(STDOUT_FILENO, "^C", 2); diff --git a/shell/hush.c b/shell/hush.c index 93ed0bc0b..6fa4e1630 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -2411,8 +2411,7 @@ static int get_user_input(struct in_str *i) /* buglet: SIGINT will not make new prompt to appear _at once_, * only after . (^C works immediately) */ r = read_line_input(G.line_input_state, prompt_str, - G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1, - /*timeout*/ -1 + G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1 ); /* read_line_input intercepts ^C, "convert" it to SIGINT */ if (r == 0) diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index e00f85864..4828c0a51 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c @@ -644,7 +644,7 @@ read_line(const char *prompt) { int sz; - sz = read_line_input(NULL, prompt, line_buffer, sizeof(line_buffer), /*timeout*/ -1); + sz = read_line_input(NULL, prompt, line_buffer, sizeof(line_buffer)); if (sz <= 0) exit(EXIT_SUCCESS); /* Ctrl-D or Ctrl-C */