[git commit master] libbb/lineedit: try to make FEATURE_EDITING_ASK_TERMINAL less ugly

Denys Vlasenko vda.linux at googlemail.com
Tue Oct 27 09:34:06 UTC 2009


commit: http://git.busybox.net/busybox/commit/?id=eb62d7c383320923e8050a24a725277a1fd5c695
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

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 <vda.linux at googlemail.com>
---
 libbb/lineedit.c |   45 +++++++++++++++++++++++++++++++++++----------
 1 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 2e1bc5d..b4c3fd3 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
 
-- 
1.6.3.3



More information about the busybox-cvs mailing list