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
