From patchwork Fri Apr 3 14:04:44 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2107 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775225191; bh=JYIC1DJKtQjXXWCprgUvRxHsuYIavImRqKMKMo+HA7w=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=RwJustc7RW090qpL0lCVCnEur8Vqn7mhc+klZUYYuTiofGJBHgN8PndC6exJKUT/0 kn3ewZBsDmBTonQEH7VW1aVra246rcSy9gGqFTwZlTEZU1T6f7ksdm2R1L+o33uO4g LgkeUAQU5iqWEqJkw+mMvlp+HMYH0jdFAx7rPKq3BNKaXNV+Tm7ABkmVQAkT/g1B89 aIUkKjrWIONZQPysa8Z1WQ1nNquFI254xQAgQDS0smjI14WTYbJg5XQ6LkY/UhHMqj C265SFsOW3Ij90V6GUekXZp9V9yTzCvvuvxUAFytX+12N5KZdho5HOqllVl6H9BJLX iMpVbHAP7YQRQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 0A6196A37D for ; Fri, 3 Apr 2026 08:06:31 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id Xl61GajF_LxU for ; Fri, 3 Apr 2026 08:06:30 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775225189; bh=JYIC1DJKtQjXXWCprgUvRxHsuYIavImRqKMKMo+HA7w=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=Hp/qbtHaSbhiS3uIHLYqI02WzUPdh0pEH2fw3p3JYuI5qLKz94C5PBgFYfG7Wm3mv w3+o3qPKqabqiiVnb9kFS7deRiZD6hK7kYIfA5Wj0M4MMHlZ8vY4ChFYTd7mFn/XxC ZOgw3Kh6Mt02GTRgWXLiTJqfUekVsK2/EvGoQbVwHBbDVkNtQkzyxqW1OhINtItshK 4RWfiXDYNiXze+KiquR6id/RjtUVoszdXuHAxe4oCP1iQwQQmyyeOTPttYijUIoD5r L/PciVv2khKYU1aGJ/8W0UKdz/XUah8EAXuuWpTEip5IKDSjeRPqD0FaXv/zfSNEfF 4geQZWRZMXFFQ== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 92C756A364 for ; Fri, 3 Apr 2026 08:06:29 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775225185; bh=GXndC6TfsnbAhau7qw3XHMSSi1AUC7EdIz21MksfFBQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hn1J06a44o2R2meQX7k7NaaCT4wB1agw4SFmHSzW2TYn1I3PAvqFyr2SQx7FDmp27 WsTCmGqm1J/sOtkOHusocio5zo3VvXM383jpQIqVeHhQ0INi8wdtp1TrV/oL2Tf3BH zGQPmOAhzAV6IIzriMr1sqjTOBOm7NVNOcjx6BUdIL+inwpzBRidBiJwQJmPMRXNyl OkZ5Y1VeHdXMFH9H4QpdinSiEWLozXPGHg6X8C/n4e2yDFflDahD7pbRB8WGd2DdBU qfds+d/zDnul6ekZWFY8TAYZ5//ugE3sqhqWjRh9xIsKMKNiIgJfmTFhsID8zduTAQ ut9QnE/6GyQFQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id CF9336A34E; Fri, 3 Apr 2026 08:06:25 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id PfMb6N_VD0Ur; Fri, 3 Apr 2026 08:06:25 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1775225184; bh=sA8imtHh4pys89EJBCbMST+9NitGplI1g8h1agLQPGg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=s0vVEz7INu/Lsc91erB7uNhQGiHZ+DXeNZCrPal3JKqBicAr3kkG/Nuuo8ZUNMOsl qFVObrwKxQdCFC3yEU5OIlqDAVJZMNpy2r4Zuj2YBTF3dyU1XAlg6rW13Z0UhajCZ0 0rt8ry4RUAZf83cw8AUmjk3uGS63UAOEl2A38LERz85+0tII7J5VAAiVRH4XEMzFja TWEmIoT0ER6akkhxNnbMBguzJE3nkk8paMdmNDdQSCaDM8aunXmjjEqX1SKJDjAiWi vIZhNwtHrDd5lFLSSTdcbu0i3zYkkEu2bo2asWFBm6X69T17P5VADmOHLoL9s8UaNu 02Gt+aJozP1cA== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 98BFF6A347; Fri, 3 Apr 2026 08:06:24 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Fri, 3 Apr 2026 08:04:44 -0600 Message-ID: <20260403140523.1998228-23-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260403140523.1998228-1-sjg@u-boot.org> References: <20260403140523.1998228-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: U7GJRLD6OEFDJVNZGIELOTGWHD3J7ZOB X-Message-ID-Hash: U7GJRLD6OEFDJVNZGIELOTGWHD3J7ZOB X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 22/34] cmd: Move VFS cat implementation to cmd/cat.c List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Move the VFS cat command from cmd/fs.c into cmd/cat.c alongside the legacy implementation. The file now uses #if IS_ENABLED(CONFIG_VFS) to select between VFS and legacy versions, avoiding duplicate command registrations. Remove the ifndef CONFIG_CMD_VFS guard in cmd/Makefile since cmd/cat.c now handles both cases. Signed-off-by: Simon Glass --- cmd/cat.c | 78 ++++++++++++++++++++++++++++++++++++--- test/dm/fs.c | 27 ++++++++++++++ test/py/tests/test_cat.py | 3 +- 3 files changed, 101 insertions(+), 7 deletions(-) diff --git a/cmd/cat.c b/cmd/cat.c index 80627f12cfc..8e0a065473d 100644 --- a/cmd/cat.c +++ b/cmd/cat.c @@ -6,11 +6,72 @@ #include #include +#include +#include #include #include #include +#include #include +#if IS_ENABLED(CONFIG_VFS) + +#define CAT_BUF_SIZE 0x1000 + +static int do_cat(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct file_uc_priv *uc_priv; + struct udevice *fil; + char buf[CAT_BUF_SIZE]; + loff_t remaining; + int ret; + + if (argc < 2) + return CMD_RET_USAGE; + + ret = vfs_open_file(argv[1], DIR_O_RDONLY, &fil); + if (ret) { + printf("Error: %dE\n", ret); + return CMD_RET_FAILURE; + } + + uc_priv = dev_get_uclass_priv(fil); + remaining = uc_priv->size; + + while (remaining > 0) { + long chunk = min((loff_t)CAT_BUF_SIZE - 1, remaining); + long nread; + + nread = file_read(fil, buf, chunk); + if (nread < 0) { + printf("Read failed: %ldE\n", nread); + return CMD_RET_FAILURE; + } + if (!nread) + break; + + buf[nread] = '\0'; + puts(buf); + remaining -= nread; + } + + return CMD_RET_SUCCESS; +} + +U_BOOT_LONGHELP(cat, + "\n" + " - Print the contents of a file in the VFS"); + +U_BOOT_CMD_COMPLETE( + cat, 2, 1, do_cat, + "print file to standard output", + cat_help_text, + vfs_cmd_complete +); + +#else /* !CONFIG_VFS */ + static int do_cat(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { @@ -29,28 +90,32 @@ static int do_cat(struct cmd_tbl *cmdtp, int flag, int argc, ret = fs_load_alloc(ifname, dev, file, 0, 0, &buf); - // check file exists + /* check file exists */ switch (ret) { case 0: break; case -ENOMEDIUM: return CMD_RET_FAILURE; case -ENOENT: - log_err("File does not exist: ifname=%s dev=%s file=%s\n", ifname, dev, file); + log_err("File does not exist: ifname=%s dev=%s file=%s\n", + ifname, dev, file); return CMD_RET_FAILURE; case -E2BIG: - log_err("File is too large: ifname=%s dev=%s file=%s\n", ifname, dev, file); + log_err("File is too large: ifname=%s dev=%s file=%s\n", + ifname, dev, file); return CMD_RET_FAILURE; case -ENOMEM: - log_err("Not enough memory: ifname=%s dev=%s file=%s\n", ifname, dev, file); + log_err("Not enough memory: ifname=%s dev=%s file=%s\n", + ifname, dev, file); return CMD_RET_FAILURE; default: case -EIO: - log_err("File-read failed: ifname=%s dev=%s file=%s\n", ifname, dev, file); + log_err("File-read failed: ifname=%s dev=%s file=%s\n", + ifname, dev, file); return CMD_RET_FAILURE; } - // print file content + /* print file content */ ((char *)buf.data)[buf.size] = '\0'; puts(buf.data); @@ -67,3 +132,4 @@ U_BOOT_CMD(cat, 4, 1, do_cat, "Print file to standard output", cat_help_text ); +#endif /* CONFIG_VFS */ diff --git a/test/dm/fs.c b/test/dm/fs.c index 8bba5263546..a8bd2a8e100 100644 --- a/test/dm/fs.c +++ b/test/dm/fs.c @@ -614,6 +614,33 @@ static int dm_test_vfs_stat(struct unit_test_state *uts) } DM_TEST(dm_test_vfs_stat, UTF_SCAN_FDT); +/* Test the cat command via VFS */ +static int dm_test_vfs_cat(struct unit_test_state *uts) +{ + ut_assertok(vfs_init()); + + ut_assertok(run_command("mount hostfs /host", 0)); + ut_assert_console_end(); + + /* Write a small file and cat it */ + memcpy(map_sysmem(0x1000, 11), "hello world", 11); + ut_assertok(run_command("save 1000 /host/.cat_test 0xb", 0)); + ut_assert_nextlinen("11 bytes"); + ut_assert_console_end(); + + ut_assertok(run_command("cat /host/.cat_test", 0)); + ut_assert_nextline("hello world"); + ut_assert_console_end(); + + os_unlink(".cat_test"); + + ut_assertok(run_command("umount /host", 0)); + ut_assert_console_end(); + + return 0; +} +DM_TEST(dm_test_vfs_cat, UTF_SCAN_FDT); + /* Test save and load round-trip via VFS */ static int dm_test_vfs_save(struct unit_test_state *uts) { diff --git a/test/py/tests/test_cat.py b/test/py/tests/test_cat.py index f793b9fe0a1..ad5ef963e8d 100644 --- a/test/py/tests/test_cat.py +++ b/test/py/tests/test_cat.py @@ -6,7 +6,8 @@ import pytest from tests.fs_helper import FsHelper -@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('sandbox') +@pytest.mark.boardspec('!sandbox') @pytest.mark.buildconfigspec('cmd_cat') def test_cat(ubman): """ Unit test for cat