aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2020-02-08 08:39:35 +0000
committerRon Yorston <rmy@pobox.com>2020-02-08 08:39:35 +0000
commit47dbad5047e6bb9fb1f287245791711ceb822c96 (patch)
tree109dfbb020216421382a7498115deff822188589
parent95f5e78e0b331996d786dc1ba099dab8f71ff63b (diff)
downloadbusybox-w32-47dbad5047e6bb9fb1f287245791711ceb822c96.tar.gz
busybox-w32-47dbad5047e6bb9fb1f287245791711ceb822c96.tar.bz2
busybox-w32-47dbad5047e6bb9fb1f287245791711ceb822c96.zip
ash: catch EOF in read builtin
The read builtin didn't detect EOF so it wasn't possible to cleanly terminate a loop like: while read -r; do echo $REPLY; done Consider how Linux handles EOF (represented as ^D, though this isn't echoed): $ awk '{print}' | xxd abc^D123 ^D 00000000: 6162 6331 3233 0a abc123. Contrast with busybox-w32 on Windows (where the ^Z is echoed): $ awk '{print}' | xxd abc^Z123 ^Z 00000000: 6162 631a 3132 330a abc.123. In both cases EOF is only detected at the start of a line. On Linux EOF within a line is dropped; on Windows it's output as a literal ctrl-Z. Implement similar behaviour for the read builtin.
-rw-r--r--shell/shell_common.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/shell/shell_common.c b/shell/shell_common.c
index af05625a4..320cd88fd 100644
--- a/shell/shell_common.c
+++ b/shell/shell_common.c
@@ -235,8 +235,8 @@ shell_builtin_read(struct builtin_read_params *params)
235 int64_t key; 235 int64_t key;
236 236
237 key = read_key(fd, NULL, timeout); 237 key = read_key(fd, NULL, timeout);
238 if (key == 0x03 || key == -1) { 238 if (key == 0x03 || key == -1 || (key == 0x1a && bufpos == 0)) {
239 /* ^C or timeout */ 239 /* ^C, timeout or ^Z at start of buffer */
240 retval = (const char *)(uintptr_t)1; 240 retval = (const char *)(uintptr_t)1;
241 goto ret; 241 goto ret;
242 } 242 }