From: Roger Knecht <rknecht@pm.me>
To: u-boot@lists.denx.de
Cc: Tom Rini <trini@konsulko.com>, Simon Glass <sjg@chromium.org>,
Heinrich Schuchardt <xypron.glpk@gmx.de>,
Roger Knecht <rknecht@pm.me>
Subject: [PATCH v6] cmd: cat: add new command
Date: Sat, 03 Sep 2022 11:34:53 +0000 [thread overview]
Message-ID: <20220903113413.411-1-rknecht@pm.me> (raw)
Add cat command to print file content to standard out
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Roger Knecht <rknecht@pm.me>
---
v6:
- Fix pylint error "Undefined variable CalledProcessError"
- Fix htmldoc error "cat.rst: document isn't included in any toctree"
v5:
- Removed "default n" from Kconfig
- Renamed 'buffer_sysmem_addr' in 'addr'
- Use yield instead of return in conftest.py
- Catch 'CalledProcessError' in conftest.py
- Clean up files after test execution
- Use u_boot_console.run_command_list() instead of u_boot_console.run_command()
- Removed unnecessary unmap_sysmem() call
- Added Reviewed-by Simon
v4:
- Return only values from enum command_ret_t in do_cat()
- Use calloc() instead of malloc() for zero initialized memory
- Make use of CONFIG_SYS_LONGHELP
- Improved error messages
v3:
- Disable 'cat' by default (CONFIG_CMD_CAT=n)
- Enable 'cat' in sandbox and sandbox64 defconfig
- Use map_to_sysmem() to fix "phys_to_virt: Cannot map sandbox address"
- Use puts() instead of a loop
- Added python test
- Added usage documentation
v2:
- Moved cat from boot to shell commands
- Added MAINTAINERS entry
- Added comments
- Improved variable naming
MAINTAINERS | 5 ++
cmd/Kconfig | 5 ++
cmd/Makefile | 1 +
cmd/cat.c | 85 ++++++++++++++++++++++++++++++
configs/sandbox64_defconfig | 1 +
configs/sandbox_defconfig | 1 +
doc/usage/cmd/cat.rst | 49 +++++++++++++++++
doc/usage/index.rst | 1 +
test/py/tests/test_cat/conftest.py | 35 ++++++++++++
test/py/tests/test_cat/test_cat.py | 20 +++++++
10 files changed, 203 insertions(+)
create mode 100644 cmd/cat.c
create mode 100644 doc/usage/cmd/cat.rst
create mode 100644 test/py/tests/test_cat/conftest.py
create mode 100644 test/py/tests/test_cat/test_cat.py
diff --git a/MAINTAINERS b/MAINTAINERS
index 36a2b69fcb..25688f2e13 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -765,6 +765,11 @@ M: Simon Glass <sjg@chromium.org>
S: Maintained
F: tools/buildman/
+CAT
+M: Roger Knecht <rknecht@pm.me>
+S: Maintained
+F: cmd/cat.c
+
CFI FLASH
M: Stefan Roese <sr@denx.de>
S: Maintained
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 8ea064b8d2..8341321f38 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1531,6 +1531,11 @@ endmenu
menu "Shell scripting commands"
+config CMD_CAT
+ bool "cat"
+ help
+ Print file to standard output
+
config CMD_ECHO
bool "echo"
default y
diff --git a/cmd/Makefile b/cmd/Makefile
index 6e87522b62..1d2590e958 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_CMD_BOOTZ) += bootz.o
obj-$(CONFIG_CMD_BOOTI) += booti.o
obj-$(CONFIG_CMD_BTRFS) += btrfs.o
obj-$(CONFIG_CMD_BUTTON) += button.o
+obj-$(CONFIG_CMD_CAT) += cat.o
obj-$(CONFIG_CMD_CACHE) += cache.o
obj-$(CONFIG_CMD_CBFS) += cbfs.o
obj-$(CONFIG_CMD_CLK) += clk.o
diff --git a/cmd/cat.c b/cmd/cat.c
new file mode 100644
index 0000000000..1273a26b14
--- /dev/null
+++ b/cmd/cat.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2022
+ * Roger Knecht <rknecht@pm.de>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <fs.h>
+#include <malloc.h>
+#include <mapmem.h>
+
+static int do_cat(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ char *ifname;
+ char *dev;
+ char *file;
+ char *buffer;
+ phys_addr_t addr;
+ loff_t file_size;
+
+ if (argc < 4)
+ return CMD_RET_USAGE;
+
+ ifname = argv[1];
+ dev = argv[2];
+ file = argv[3];
+
+ // check file exists
+ if (fs_set_blk_dev(ifname, dev, FS_TYPE_ANY))
+ return CMD_RET_FAILURE;
+
+ if (!fs_exists(file)) {
+ log_err("File does not exist: ifname=%s dev=%s file=%s\n", ifname, dev, file);
+ return CMD_RET_FAILURE;
+ }
+
+ // get file size
+ if (fs_set_blk_dev(ifname, dev, FS_TYPE_ANY))
+ return CMD_RET_FAILURE;
+
+ if (fs_size(file, &file_size)) {
+ log_err("Cannot read file size: ifname=%s dev=%s file=%s\n", ifname, dev, file);
+ return CMD_RET_FAILURE;
+ }
+
+ // allocate memory for file content
+ buffer = calloc(sizeof(char), file_size + 1);
+ if (!buffer) {
+ log_err("Out of memory\n");
+ return CMD_RET_FAILURE;
+ }
+
+ // map pointer to system memory
+ addr = map_to_sysmem(buffer);
+
+ // read file to memory
+ if (fs_set_blk_dev(ifname, dev, FS_TYPE_ANY))
+ return CMD_RET_FAILURE;
+
+ if (fs_read(file, addr, 0, 0, &file_size)) {
+ log_err("Cannot read file: ifname=%s dev=%s file=%s\n", ifname, dev, file);
+ return CMD_RET_FAILURE;
+ }
+
+ // print file content
+ buffer[file_size] = '\0';
+ puts(buffer);
+
+ free(buffer);
+
+ return 0;
+}
+
+#ifdef CONFIG_SYS_LONGHELP
+static char cat_help_text[] =
+ "<interface> <dev[:part]> <file>\n"
+ " - Print file from 'dev' on 'interface' to standard output\n";
+#endif
+
+U_BOOT_CMD(cat, 4, 1, do_cat,
+ "Print file to standard output",
+ cat_help_text
+);
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index 290d1506c2..cdf9745ed9 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -22,6 +22,7 @@ CONFIG_CONSOLE_RECORD=y
CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
CONFIG_PRE_CONSOLE_BUFFER=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_CMD_CAT=y
CONFIG_CMD_CPU=y
CONFIG_CMD_LICENSE=y
CONFIG_CMD_BOOTZ=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index ab5d3f19bf..519b40a7c6 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -36,6 +36,7 @@ CONFIG_LOG_DEFAULT_LEVEL=6
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_STACKPROTECTOR=y
CONFIG_ANDROID_AB=y
+CONFIG_CMD_CAT=y
CONFIG_CMD_CPU=y
CONFIG_CMD_LICENSE=y
CONFIG_CMD_BOOTM_PRE_LOAD=y
diff --git a/doc/usage/cmd/cat.rst b/doc/usage/cmd/cat.rst
new file mode 100644
index 0000000000..5ef4731fe3
--- /dev/null
+++ b/doc/usage/cmd/cat.rst
@@ -0,0 +1,49 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+cat command
+===============
+
+Synopsis
+--------
+
+::
+
+ cat <interface> <dev[:part]> <file>
+
+Description
+-----------
+
+The cat command prints the file content to standard out.
+
+interface
+ interface for accessing the block device (mmc, sata, scsi, usb, ....)
+
+dev
+ device number
+
+part
+ partition number, defaults to 1
+
+file
+ path to file
+
+Example
+-------
+
+Here is the output for a example text file:
+
+::
+
+ => cat mmc 0:1 hello
+ hello world
+ =>
+
+Configuration
+-------------
+
+The cat command is only available if CONFIG_CMD_CAT=y.
+
+Return value
+------------
+
+The return value $? is set to 0 (true) if the file is readable, otherwise it returns a non-zero error code.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 28f9683a3e..4c2d56bae6 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -31,6 +31,7 @@ Shell commands
cmd/bootmeth
cmd/button
cmd/bootz
+ cmd/cat
cmd/cbsysinfo
cmd/conitrace
cmd/dm
diff --git a/test/py/tests/test_cat/conftest.py b/test/py/tests/test_cat/conftest.py
new file mode 100644
index 0000000000..058fe52352
--- /dev/null
+++ b/test/py/tests/test_cat/conftest.py
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+"""Fixture for cat command test
+"""
+
+import os
+import shutil
+from subprocess import check_call, CalledProcessError
+import pytest
+
+@pytest.fixture(scope='session')
+def cat_data(u_boot_config):
+ """Set up a file system to be used in cat tests
+
+ Args:
+ u_boot_config -- U-boot configuration.
+ """
+ mnt_point = u_boot_config.persistent_data_dir + '/test_cat'
+ image_path = u_boot_config.persistent_data_dir + '/cat.img'
+
+ try:
+ os.mkdir(mnt_point, mode = 0o755)
+
+ with open(mnt_point + '/hello', 'w', encoding = 'ascii') as file:
+ file.write('hello world\n')
+
+ check_call(f'virt-make-fs --partition=gpt --size=+1M --type=vfat {mnt_point} {image_path}',
+ shell=True)
+
+ yield image_path
+ except CalledProcessError:
+ pytest.skip('Setup failed')
+ finally:
+ shutil.rmtree(mnt_point)
+ os.remove(image_path)
diff --git a/test/py/tests/test_cat/test_cat.py b/test/py/tests/test_cat/test_cat.py
new file mode 100644
index 0000000000..132527bd4c
--- /dev/null
+++ b/test/py/tests/test_cat/test_cat.py
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+""" Unit test for cat command
+"""
+
+import pytest
+
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.buildconfigspec('cmd_cat')
+def test_cat(u_boot_console, cat_data):
+ """ Unit test for cat
+
+ Args:
+ u_boot_console -- U-Boot console
+ cat_data -- Path to the disk image used for testing.
+ """
+ response = u_boot_console.run_command_list([
+ f'host bind 0 {cat_data}',
+ 'cat host 0 hello'])
+ assert 'hello world' in response
--
2.25.1
next reply other threads:[~2022-09-03 11:35 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-03 11:34 Roger Knecht [this message]
2022-10-11 21:36 ` [PATCH v6] cmd: cat: add new command Tom Rini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220903113413.411-1-rknecht@pm.me \
--to=rknecht@pm.me \
--cc=sjg@chromium.org \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
--cc=xypron.glpk@gmx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.