* [PATCH] commands: cat: add support for concatenating into file
@ 2026-01-26 10:59 Ahmad Fatoum
2026-01-27 7:33 ` Sascha Hauer
0 siblings, 1 reply; 2+ messages in thread
From: Ahmad Fatoum @ 2026-01-26 10:59 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
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 <a.fatoum@pengutronix.de>
---
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
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] commands: cat: add support for concatenating into file
2026-01-26 10:59 [PATCH] commands: cat: add support for concatenating into file Ahmad Fatoum
@ 2026-01-27 7:33 ` Sascha Hauer
0 siblings, 0 replies; 2+ messages in thread
From: Sascha Hauer @ 2026-01-27 7:33 UTC (permalink / raw)
To: barebox, Ahmad Fatoum
On Mon, 26 Jan 2026 11:59:52 +0100, Ahmad Fatoum wrote:
> 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.
>
>
Applied, thanks!
[1/1] commands: cat: add support for concatenating into file
https://git.pengutronix.de/cgit/barebox/commit/?id=5f8d817aa34b (link may not be stable)
Best regards,
--
Sascha Hauer <s.hauer@pengutronix.de>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-01-27 7:34 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-01-26 10:59 [PATCH] commands: cat: add support for concatenating into file Ahmad Fatoum
2026-01-27 7:33 ` Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox