ash: fix bad interaction of "stty -echo" + ASK_TERMINAL
function old new delta read_line_input 4820 4886 +66 put_prompt 108 47 -61 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 66/-61) Total: 5 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
b6d221ac9c
commit
13ad90627c
@ -372,55 +372,14 @@ static void input_backward(unsigned num)
|
|||||||
|
|
||||||
static void put_prompt(void)
|
static void put_prompt(void)
|
||||||
{
|
{
|
||||||
|
unsigned w;
|
||||||
|
|
||||||
out1str(cmdedit_prompt);
|
out1str(cmdedit_prompt);
|
||||||
fflush_all();
|
fflush_all();
|
||||||
#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_all(); /* make terminal see it ASAP! */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
{
|
w = cmdedit_termw; /* read volatile var once */
|
||||||
unsigned w = cmdedit_termw; /* volatile var */
|
cmdedit_y = cmdedit_prmt_len / w; /* new quasireal y */
|
||||||
cmdedit_y = cmdedit_prmt_len / w; /* new quasireal y */
|
cmdedit_x = cmdedit_prmt_len % w;
|
||||||
cmdedit_x = cmdedit_prmt_len % w;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* draw prompt, editor line, and clear tail */
|
/* draw prompt, editor line, and clear tail */
|
||||||
@ -1503,6 +1462,51 @@ static void ctrl_right(void)
|
|||||||
* read_line_input and its helpers
|
* 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
|
#if !ENABLE_FEATURE_EDITING_FANCY_PROMPT
|
||||||
static void parse_and_put_prompt(const char *prmt_ptr)
|
static void parse_and_put_prompt(const char *prmt_ptr)
|
||||||
{
|
{
|
||||||
@ -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);
|
bb_error_msg("cur_history:%d cnt_history:%d", state->cur_history, state->cnt_history);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Print out the command prompt */
|
/* Print out the command prompt, optionally ask where cursor is */
|
||||||
parse_and_put_prompt(prompt);
|
parse_and_put_prompt(prompt);
|
||||||
|
ask_terminal();
|
||||||
|
|
||||||
read_key_buffer[0] = 0;
|
read_key_buffer[0] = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
Loading…
Reference in New Issue
Block a user