From eb62d7c383320923e8050a24a725277a1fd5c695 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Oct 2009 10:34:06 +0100 Subject: libbb/lineedit: try to make FEATURE_EDITING_ASK_TERMINAL less ugly function old new delta read_line_input 4809 4829 +20 lineedit_read_key 207 223 +16 put_prompt 110 117 +7 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 43/0) Total: 43 bytes Signed-off-by: Denys Vlasenko --- libbb/lineedit.c | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 2e1bc5d2e..b4c3fd35c 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -140,6 +140,9 @@ struct lineedit_statics { smallint newdelflag; /* whether delbuf should be reused yet */ CHAR_T delbuf[DELBUFSIZ]; /* a place to store deleted characters */ #endif +#if ENABLE_FEATURE_EDITING_ASK_TERMINAL + smallint sent_ESC_br_n6; +#endif /* Formerly these were big buffers on stack: */ #if ENABLE_FEATURE_TAB_COMPLETION @@ -371,7 +374,8 @@ static void put_prompt(void) { out1str(cmdedit_prompt); fflush(NULL); - if (ENABLE_FEATURE_EDITING_ASK_TERMINAL) { +#if ENABLE_FEATURE_EDITING_ASK_TERMINAL + { /* Ask terminal where is the cursor now. * lineedit_read_key handles response and corrects * our idea of current cursor position. @@ -405,10 +409,12 @@ static void put_prompt(void) pfd.fd = STDIN_FILENO; pfd.events = POLLIN; if (safe_poll(&pfd, 1, 0) == 0) { + S.sent_ESC_br_n6 = 1; out1str("\033" "[6n"); fflush(NULL); /* make terminal see it ASAP! */ } } +#endif cursor = 0; { unsigned w = cmdedit_termw; /* volatile var */ @@ -1666,20 +1672,24 @@ static int lineedit_read_key(char *read_key_buffer) /* Note: read_key sets errno to 0 on success: */ ic = read_key(STDIN_FILENO, read_key_buffer); - if (ENABLE_FEATURE_EDITING_ASK_TERMINAL - && cursor == 0 /* otherwise it may be bogus */ - && (int32_t)ic == KEYCODE_CURSOR_POS +#if ENABLE_FEATURE_EDITING_ASK_TERMINAL + if ((int32_t)ic == KEYCODE_CURSOR_POS + && S.sent_ESC_br_n6 ) { - int col = ((ic >> 32) & 0x7fff) - 1; - if (col > cmdedit_prmt_len) { - cmdedit_x += (col - cmdedit_prmt_len); - while (cmdedit_x >= cmdedit_termw) { - cmdedit_x -= cmdedit_termw; - cmdedit_y++; + S.sent_ESC_br_n6 = 0; + if (cursor == 0) { /* otherwise it may be bogus */ + int col = ((ic >> 32) & 0x7fff) - 1; + if (col > cmdedit_prmt_len) { + cmdedit_x += (col - cmdedit_prmt_len); + while (cmdedit_x >= cmdedit_termw) { + cmdedit_x -= cmdedit_termw; + cmdedit_y++; + } } } goto poll_again; } +#endif #if ENABLE_FEATURE_ASSUME_UNICODE { @@ -2192,6 +2202,21 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li #endif } /* while (1) */ +#if ENABLE_FEATURE_EDITING_ASK_TERMINAL + if (S.sent_ESC_br_n6) { + /* "sleep 1; busybox ash" + hold [Enter] to trigger. + * We sent "ESC [ 6 n", but got '\n' first, and + * KEYCODE_CURSOR_POS response is now buffered from terminal. + * It's bad already and not much can be done with it + * (it _will_ be visible for the next process to read stdin), + * but without this delay it even shows up on the screen + * as garbage because we restore echo settings with tcsetattr + * before it comes in. UGLY! + */ + usleep(20*1000); + } +#endif + /* Stop bug catching using "command_must_not_be_used" trick */ #undef command -- cgit v1.2.3