For testing initrd concatenation, it would be useful if barebox could
repeat the operation on the shell and then it can compare it against
the result, so add cat -o and -a options, like we already got for
echo.

Signed-off-by: Ahmad Fatoum <[email protected]>
---
 commands/cat.c        | 76 ++++++++++++++++++++++++++++++++++---------
 test/py/test_shell.py | 32 ++++++++++++++++++
 2 files changed, 92 insertions(+), 16 deletions(-)

diff --git a/commands/cat.c b/commands/cat.c
index 503520dc64a5..aa77b19907e0 100644
--- a/commands/cat.c
+++ b/commands/cat.c
@@ -14,6 +14,8 @@
 #include <errno.h>
 #include <xfuncs.h>
 #include <malloc.h>
+#include <getopt.h>
+#include <libfile.h>
 
 #define BUFSIZE 1024
 
@@ -23,20 +25,46 @@
  */
 static int do_cat(int argc, char *argv[])
 {
+       const char *outfile = NULL;
        int ret;
-       int fd, i;
+       int fd, outfd = -1, i;
        char *buf;
        int err = 0;
-       int args = 1;
+       int oflags = O_WRONLY | O_CREAT;
+       int opt;
 
-       if (argc < 2) {
-               perror("cat");
-               return 1;
+       while ((opt = getopt(argc, argv, "a:o:")) > 0) {
+               switch(opt) {
+               case 'a':
+                       oflags |= O_APPEND;
+                       outfile = optarg;
+                       break;
+               case 'o':
+                       oflags |= O_TRUNC;
+                       outfile = optarg;
+                       break;
+               default:
+                       return COMMAND_ERROR_USAGE;
+               }
+       }
+
+       argv += optind;
+       argc -= optind;
+
+       if (argc == 0)
+               return COMMAND_ERROR_USAGE;
+
+       if (outfile) {
+               outfd = open(outfile, oflags);
+               if (outfd < 0) {
+                       perror("open");
+                       return 1;
+               }
        }
 
        buf = xmalloc(BUFSIZE);
 
-       while (args < argc) {
+       for (int args = 0; args < argc; args++) {
                fd = open(argv[args], O_RDONLY);
                if (fd < 0) {
                        err = 1;
@@ -44,24 +72,36 @@ static int do_cat(int argc, char *argv[])
                        goto out;
                }
 
-               while((ret = read(fd, buf, BUFSIZE)) > 0) {
-                       for(i = 0; i < ret; i++) {
-                               if (isprint(buf[i]) || buf[i] == '\n' || buf[i] 
== '\t')
-                                       putchar(buf[i]);
-                               else
-                                       putchar('.');
-                       }
-                       if(ctrlc()) {
+
+               if (outfd >= 0) {
+                       ret = copy_fd(fd, outfd, 0);
+                       if (ret < 0) {
+                               perror("copy_fd");
                                err = 1;
                                close(fd);
                                goto out;
                        }
+               } else {
+                       while((ret = read(fd, buf, BUFSIZE)) > 0) {
+                               for (i = 0; i < ret; i++) {
+                                       if (isprint(buf[i]) || buf[i] == '\n' 
|| buf[i] == '\t')
+                                               putchar(buf[i]);
+                                       else
+                                               putchar('.');
+                               }
+                               if(ctrlc()) {
+                                       err = 1;
+                                       close(fd);
+                                       goto out;
+                               }
+                       }
                }
+
                close(fd);
-               args++;
        }
 
 out:
+       close(outfd);
        free(buf);
 
        return err;
@@ -69,12 +109,16 @@ static int do_cat(int argc, char *argv[])
 
 BAREBOX_CMD_HELP_START(cat)
 BAREBOX_CMD_HELP_TEXT("Currently only printable characters and NL, TAB are 
printed.")
+BAREBOX_CMD_HELP_TEXT("")
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT ("-a FILE", "append to FILE instead of using stdout")
+BAREBOX_CMD_HELP_OPT ("-o FILE", "overwrite FILE instead of using stdout")
 BAREBOX_CMD_HELP_END
 
 BAREBOX_CMD_START(cat)
        .cmd            = do_cat,
        BAREBOX_CMD_DESC("concatenate file(s) to stdout")
-       BAREBOX_CMD_OPTS("FILE...")
+       BAREBOX_CMD_OPTS("[-ao] FILE...")
        BAREBOX_CMD_GROUP(CMD_GRP_FILE)
        BAREBOX_CMD_HELP(cmd_cat_help)
 BAREBOX_CMD_END
diff --git a/test/py/test_shell.py b/test/py/test_shell.py
index 50ae497fc6c3..9010270e0e63 100644
--- a/test/py/test_shell.py
+++ b/test/py/test_shell.py
@@ -32,6 +32,38 @@ def test_shell_quoting(barebox):
     assert barebox.run_check('source /tmp/script && echo "$var"') == "A B"
 
 
+def test_barebox_echo_cat(barebox, barebox_config):
+    skip_disabled(barebox_config, "CONFIG_CMD_ECHO", "CONFIG_CMD_CAT")
+
+    barebox.run_check('rm -f stanza*')
+
+    barebox.run_check('echo -o stanza-1 meow')
+    barebox.run_check('echo -o stanza-1 mau')
+    barebox.run_check('echo -o stanza-2 meow')
+    barebox.run_check('echo -a stanza-2 meow')
+    barebox.run_check('cat  -o stanza-3 /dev/null')
+    barebox.run_check('echo -a stanza-3 mau')
+    barebox.run_check('echo -a stanza-3 ma')
+
+    expected = ["mau", "meow", "meow", "mau", "ma"]
+
+    stdout = barebox.run_check('ls -l stanza-*')
+
+    assert len(stdout) == 3
+
+    assert barebox.run_check('cat stanza-*') == expected
+
+    barebox.run_check('rm -f stanza')
+
+    stdout = barebox.run_check('cat -o stanza stanza-*')
+    assert stdout == []
+    assert barebox.run_check('cat stanza') == expected
+
+    stdout = barebox.run_check('cat -a stanza stanza-*')
+    assert stdout == []
+    assert barebox.run_check('cat stanza') == expected + expected
+
+
 def test_barebox_md5sum(barebox, barebox_config):
     skip_disabled(barebox_config, "CONFIG_CMD_MD5SUM", "CONFIG_CMD_ECHO")
 
-- 
2.47.3


Reply via email to