aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
Diffstat (limited to 'libbb')
-rw-r--r--libbb/lineedit.c11
-rw-r--r--libbb/read_key.c13
2 files changed, 15 insertions, 9 deletions
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index a0b1bcf8e..81f6fdeff 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -1451,10 +1451,13 @@ static int lineedit_read_key(char *read_key_buffer)
pfd.events = POLLIN;
do {
poll_again:
- /* Wait for input. Can't just call read_key, it will return
- * at once if stdin is in non-blocking mode. */
- safe_poll(&pfd, 1, -1);
- /* note: read_key sets errno to 0 on success: */
+ if (read_key_buffer[0] == 0) {
+ /* Wait for input. Can't just call read_key,
+ * it returns at once if stdin
+ * is in non-blocking mode. */
+ safe_poll(&pfd, 1, -1);
+ }
+ /* Note: read_key sets errno to 0 on success: */
ic = read_key(STDIN_FILENO, read_key_buffer);
if (ENABLE_FEATURE_EDITING_ASK_TERMINAL
&& (int32_t)ic == KEYCODE_CURSOR_POS
diff --git a/libbb/read_key.c b/libbb/read_key.c
index 3771045d2..6f6c39e45 100644
--- a/libbb/read_key.c
+++ b/libbb/read_key.c
@@ -69,11 +69,14 @@ int64_t FAST_FUNC read_key(int fd, char *buffer)
errno = 0;
n = (unsigned char) *buffer++;
if (n == 0) {
- /* If no data, block waiting for input. If we read more
- * than the minimal ESC sequence size, the "n=0" below
- * would instead have to figure out how much to keep,
- * resulting in larger code. */
- n = safe_read(fd, buffer, 3);
+ /* If no data, block waiting for input.
+ * It is tempting to read more than one byte here,
+ * but it breaks pasting. Example: at shell prompt,
+ * user presses "c","a","t" and then pastes "\nline\n".
+ * When we were reading 3 bytes here, we were eating
+ * "li" too, and cat was getting wrong input.
+ */
+ n = safe_read(fd, buffer, 1);
if (n <= 0)
return -1;
}