diff options
author | Ron Yorston <rmy@pobox.com> | 2020-02-08 08:39:35 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2020-02-08 08:39:35 +0000 |
commit | 47dbad5047e6bb9fb1f287245791711ceb822c96 (patch) | |
tree | 109dfbb020216421382a7498115deff822188589 | |
parent | 95f5e78e0b331996d786dc1ba099dab8f71ff63b (diff) | |
download | busybox-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.c | 4 |
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 | } |