cmd: cat: add new command

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>
This commit is contained in:
Roger Knecht 2022-09-03 11:34:53 +00:00 committed by Tom Rini
parent 7eda1a9533
commit 690a1d6948
10 changed files with 203 additions and 0 deletions

View file

@ -786,6 +786,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

View file

@ -1533,6 +1533,11 @@ endmenu
menu "Shell scripting commands"
config CMD_CAT
bool "cat"
help
Print file to standard output
config CMD_ECHO
bool "echo"
default y

View file

@ -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

85
cmd/cat.c Normal file
View file

@ -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
);

View file

@ -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

View file

@ -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

49
doc/usage/cmd/cat.rst Normal file
View file

@ -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.

View file

@ -31,6 +31,7 @@ Shell commands
cmd/bootmeth
cmd/button
cmd/bootz
cmd/cat
cmd/cbsysinfo
cmd/cls
cmd/conitrace

View file

@ -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)

View file

@ -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