traceroute: fix help text to not show -6 when traceroute6 is off
[oweals/busybox.git] / libbb / lineedit.c
index 0f7ab8c94d43b0b5fe5d8fbc2c646ba775ac6d7b..7bb3f2e356489bfd083e45efd20f3a7f7199c657 100644 (file)
@@ -372,55 +372,14 @@ static void input_backward(unsigned num)
 
 static void put_prompt(void)
 {
+       unsigned w;
+
        out1str(cmdedit_prompt);
-       fflush(NULL);
-#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.
-                * Testcase: run "echo -n long_line_long_line_long_line",
-                * then type in a long, wrapping command and try to
-                * delete it using backspace key.
-                * Note: we print it _after_ prompt, because
-                * prompt may contain CR. Example: PS1='\[\r\n\]\w '
-                */
-               /* Problem: if there is buffered input on stdin,
-                * the response will be delivered later,
-                * possibly to an unsuspecting application.
-                * Testcase: "sleep 1; busybox ash" + press and hold [Enter].
-                * Result:
-                * ~/srcdevel/bbox/fix/busybox.t4 #
-                * ~/srcdevel/bbox/fix/busybox.t4 #
-                * ^[[59;34~/srcdevel/bbox/fix/busybox.t4 #  <-- garbage
-                * ~/srcdevel/bbox/fix/busybox.t4 #
-                *
-                * Checking for input with poll only makes the race narrower,
-                * I still can trigger it. Strace:
-                *
-                * write(1, "~/srcdevel/bbox/fix/busybox.t4 # ", 33) = 33
-                * poll([{fd=0, events=POLLIN}], 1, 0) = 0 (Timeout)  <-- no input exists
-                * write(1, "\33[6n", 4) = 4  <-- send the ESC sequence, quick!
-                * poll([{fd=0, events=POLLIN}], 1, 4294967295) = 1 ([{fd=0, revents=POLLIN}])
-                * read(0, "\n", 1)      = 1  <-- oh crap, user's input got in first
-                */
-               struct pollfd pfd;
-
-               pfd.fd = STDIN_FILENO;
-               pfd.events = POLLIN;
-               if (safe_poll(&pfd, 1, 0) == 0) {
-                       S.sent_ESC_br6n = 1;
-                       out1str("\033" "[6n");
-                       fflush(NULL); /* make terminal see it ASAP! */
-               }
-       }
-#endif
+       fflush_all();
        cursor = 0;
-       {
-               unsigned w = cmdedit_termw; /* volatile var */
-               cmdedit_y = cmdedit_prmt_len / w; /* new quasireal y */
-               cmdedit_x = cmdedit_prmt_len % w;
-       }
+       w = cmdedit_termw; /* read volatile var once */
+       cmdedit_y = cmdedit_prmt_len / w; /* new quasireal y */
+       cmdedit_x = cmdedit_prmt_len % w;
 }
 
 /* draw prompt, editor line, and clear tail */
@@ -1503,6 +1462,51 @@ static void ctrl_right(void)
  * read_line_input and its helpers
  */
 
+#if ENABLE_FEATURE_EDITING_ASK_TERMINAL
+static void ask_terminal(void)
+{
+       /* Ask terminal where is the cursor now.
+        * lineedit_read_key handles response and corrects
+        * our idea of current cursor position.
+        * Testcase: run "echo -n long_line_long_line_long_line",
+        * then type in a long, wrapping command and try to
+        * delete it using backspace key.
+        * Note: we print it _after_ prompt, because
+        * prompt may contain CR. Example: PS1='\[\r\n\]\w '
+        */
+       /* Problem: if there is buffered input on stdin,
+        * the response will be delivered later,
+        * possibly to an unsuspecting application.
+        * Testcase: "sleep 1; busybox ash" + press and hold [Enter].
+        * Result:
+        * ~/srcdevel/bbox/fix/busybox.t4 #
+        * ~/srcdevel/bbox/fix/busybox.t4 #
+        * ^[[59;34~/srcdevel/bbox/fix/busybox.t4 #  <-- garbage
+        * ~/srcdevel/bbox/fix/busybox.t4 #
+        *
+        * Checking for input with poll only makes the race narrower,
+        * I still can trigger it. Strace:
+        *
+        * write(1, "~/srcdevel/bbox/fix/busybox.t4 # ", 33) = 33
+        * poll([{fd=0, events=POLLIN}], 1, 0) = 0 (Timeout)  <-- no input exists
+        * write(1, "\33[6n", 4) = 4  <-- send the ESC sequence, quick!
+        * poll([{fd=0, events=POLLIN}], 1, 4294967295) = 1 ([{fd=0, revents=POLLIN}])
+        * read(0, "\n", 1)      = 1  <-- oh crap, user's input got in first
+        */
+       struct pollfd pfd;
+
+       pfd.fd = STDIN_FILENO;
+       pfd.events = POLLIN;
+       if (safe_poll(&pfd, 1, 0) == 0) {
+               S.sent_ESC_br6n = 1;
+               out1str("\033" "[6n");
+               fflush_all(); /* make terminal see it ASAP! */
+       }
+}
+#else
+#define ask_terminal() ((void)0)
+#endif
+
 #if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
 static void parse_and_put_prompt(const char *prmt_ptr)
 {
@@ -1636,7 +1640,7 @@ static void cmdedit_setwidth(unsigned w, int redraw_flg)
                int new_y = (cursor + cmdedit_prmt_len) / w;
                /* redraw */
                redraw((new_y >= cmdedit_y ? new_y : cmdedit_y), command_len - cursor);
-               fflush(NULL);
+               fflush_all();
        }
 }
 
@@ -1748,7 +1752,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
        ) {
                /* Happens when e.g. stty -echo was run before */
                parse_and_put_prompt(prompt);
-               /* fflush(stdout); - done by parse_and_put_prompt */
+               /* fflush_all(); - done by parse_and_put_prompt */
                if (fgets(command, maxsize, stdin) == NULL)
                        len = -1; /* EOF or error */
                else
@@ -1822,8 +1826,9 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
        bb_error_msg("cur_history:%d cnt_history:%d", state->cur_history, state->cnt_history);
 #endif
 
-       /* Print out the command prompt */
+       /* Print out the command prompt, optionally ask where cursor is */
        parse_and_put_prompt(prompt);
+       ask_terminal();
 
        read_key_buffer[0] = 0;
        while (1) {
@@ -1841,7 +1846,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
                };
                int32_t ic, ic_raw;
 
-               fflush(NULL);
+               fflush_all();
                ic = ic_raw = lineedit_read_key(read_key_buffer);
 
 #if ENABLE_FEATURE_EDITING_VI
@@ -2245,7 +2250,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
        tcsetattr_stdin_TCSANOW(&initial_settings);
        /* restore SIGWINCH handler */
        signal(SIGWINCH, previous_SIGWINCH_handler);
-       fflush(NULL);
+       fflush_all();
 
        len = command_len;
        DEINIT_S();
@@ -2259,7 +2264,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
 int FAST_FUNC read_line_input(const char* prompt, char* command, int maxsize)
 {
        fputs(prompt, stdout);
-       fflush(NULL);
+       fflush_all();
        fgets(command, maxsize, stdin);
        return strlen(command);
 }