Make the read built-in more compatible with bash:

- Return an exit code of 142 on timeout.

- When the timeout expires before a newline is detected in the
  input bash captures the partial input.  This behaviour is new
  since bash version 4.4.  BusyBox shells had the pre-4.4 behaviour
  where the input was lost.

Update the tests to suit and fix a couple of compiler errors in
the testsuite.

function                                             old     new   delta
builtin_read                                         154     174     +20
readcmd                                              213     228     +15
shell_builtin_read                                  1364    1370      +6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 41/0)               Total: 41 bytes

v2: Check for errors other than EINTR.  Thanks to Harald van Dijk
    for pointing out my misplaced faith in comments.

Signed-off-by: Ron Yorston <[email protected]>
---
 shell/ash.c                          |  3 +++
 shell/ash_test/ash-read/read_t.right |  8 ++++----
 shell/ash_test/ash-read/read_t.tests | 18 +++++++++---------
 shell/ash_test/printenv.c            |  4 +---
 shell/ash_test/recho.c               |  2 +-
 shell/hush.c                         |  3 +++
 shell/shell_common.c                 | 10 +++++++---
 7 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index 9173b8608..60b782e41 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -14395,6 +14395,9 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
                        goto again;
        }
 
+       if ((uintptr_t)r == 2)
+               return 128 + SIGALRM;
+
        if ((uintptr_t)r > 1)
                ash_msg_and_raise_error(r);
 
diff --git a/shell/ash_test/ash-read/read_t.right 
b/shell/ash_test/ash-read/read_t.right
index 04126cbe6..3eedae275 100644
--- a/shell/ash_test/ash-read/read_t.right
+++ b/shell/ash_test/ash-read/read_t.right
@@ -1,4 +1,4 @@
-><
-><
->test<
->test<
+>te:142<
+>:142<
+>test:0<
+>test:0<
diff --git a/shell/ash_test/ash-read/read_t.tests 
b/shell/ash_test/ash-read/read_t.tests
index d65f1aeaa..9fbeec517 100755
--- a/shell/ash_test/ash-read/read_t.tests
+++ b/shell/ash_test/ash-read/read_t.tests
@@ -1,10 +1,10 @@
-# bash 3.2 outputs:
+# bash 5.2 outputs:
 
-# ><
-{ echo -n 'te'; sleep 2; echo 'st'; }   | (read -t 1 reply; echo ">$reply<")
-# ><
-{               sleep 2; echo 'test'; } | (read -t 1 reply; echo ">$reply<")
-# >test<
-{ echo -n 'te'; sleep 1; echo 'st'; }   | (read -t 2 reply; echo ">$reply<")
-# >test<
-{               sleep 1; echo 'test'; } | (read -t 2 reply; echo ">$reply<")
+# >te:142<
+{ echo -n 'te'; sleep 2; echo 'st'; }   | (read -t 1 reply; echo ">$reply:$?<")
+# >:142<
+{               sleep 2; echo 'test'; } | (read -t 1 reply; echo ">$reply:$?<")
+# >test:0<
+{ echo -n 'te'; sleep 1; echo 'st'; }   | (read -t 2 reply; echo ">$reply:$?<")
+# >test:0<
+{               sleep 1; echo 'test'; } | (read -t 2 reply; echo ">$reply:$?<")
diff --git a/shell/ash_test/printenv.c b/shell/ash_test/printenv.c
index c86308d3b..f0f41984d 100644
--- a/shell/ash_test/printenv.c
+++ b/shell/ash_test/printenv.c
@@ -31,9 +31,7 @@
 extern char **environ;
 
 int
-main (argc, argv)
-     int argc;
-     char **argv;
+main (int argc, char **argv)
 {
   register char **envp, *eval;
   int len;
diff --git a/shell/ash_test/recho.c b/shell/ash_test/recho.c
index 42a5feafd..7e96b14cc 100644
--- a/shell/ash_test/recho.c
+++ b/shell/ash_test/recho.c
@@ -27,7 +27,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-void strprint();
+void strprint(char *);
 
 int main(int argc, char **argv)
 {
diff --git a/shell/hush.c b/shell/hush.c
index 4a97293cc..9f94bfdec 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -11175,6 +11175,9 @@ static int FAST_FUNC builtin_read(char **argv)
                        goto again;
        }
 
+       if ((uintptr_t)r == 2)
+               return 128 + SIGALRM;
+
        if ((uintptr_t)r > 1) {
                bb_simple_error_msg(r);
                r = (char*)(uintptr_t)1;
diff --git a/shell/shell_common.c b/shell/shell_common.c
index e5c2cefb3..9a03f7265 100644
--- a/shell/shell_common.c
+++ b/shell/shell_common.c
@@ -204,8 +204,8 @@ shell_builtin_read(struct builtin_read_params *params)
                         * 32-bit unix time wrapped (year 2038+).
                         */
                        if (timeout <= 0) { /* already late? */
-                               retval = (const char *)(uintptr_t)1;
-                               goto ret;
+                               retval = (const char *)(uintptr_t)2;
+                               break;
                        }
                }
 
@@ -217,8 +217,12 @@ shell_builtin_read(struct builtin_read_params *params)
                pfd[0].events = POLLIN;
 //TODO race with a signal arriving just before the poll!
                if (poll(pfd, 1, timeout) <= 0) {
-                       /* timed out, or EINTR */
+                       /* timed out, or some error */
                        err = errno;
+                       if (!err) {
+                               retval = (const char *)(uintptr_t)2;
+                               break;
+                       }
                        retval = (const char *)(uintptr_t)1;
                        goto ret;
                }
-- 
2.50.0

_______________________________________________
busybox mailing list
[email protected]
https://lists.busybox.net/mailman/listinfo/busybox

Reply via email to