[PATCH v4 13/14] cmd: fastboot: Use getopt() for option parsing

Simon Glass sjg at chromium.org
Wed Jul 1 13:42:33 CEST 2026


do_fastboot() hand-rolls the same shape as the gnarliest env parsers:
an outer loop over - arguments, an inner while (*++arg) to split
grouped flags, and a goto NXTARG to skip the rest of the element after
-l or -s has consumed the following argument for its address or size.

Replace it with getopt(). do_fastboot() does not use cmdtp or flag, so
move it to the getopt-state command signature, declared with
U_BOOT_CMD_GETOPT(); -l and -s take their arguments from gs->arg. Keep
the + prefix on the optstring so getopt() stops at the first
non-option, exactly as the hand-rolled loop did, and hand the transport
and controller arguments that follow to the do_fastboot_{usb,udp,tcp}()
helpers unchanged via gs->argv[gs->index - 1] (which keeps argv[1]
pointing at the first positional, as before). The - only
controller-index case still falls through to the same error.

CMD_FASTBOOT selects GETOPT so the parser is linked in on boards that
do not already enable it.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v4:
- Add new patch to convert fastboot

 cmd/Kconfig    |  1 +
 cmd/fastboot.c | 48 +++++++++++++++++++++---------------------------
 2 files changed, 22 insertions(+), 27 deletions(-)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 9cafeb5d07c..e100a08d271 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1202,6 +1202,7 @@ config CMD_DM
 config CMD_FASTBOOT
 	bool "fastboot - Android fastboot support"
 	depends on FASTBOOT
+	select GETOPT
 	help
 	  This enables the command "fastboot" which enables the Android
 	  fastboot mode for the platform. Fastboot is a protocol for
diff --git a/cmd/fastboot.c b/cmd/fastboot.c
index f3929f88dfa..c780927ac72 100644
--- a/cmd/fastboot.c
+++ b/cmd/fastboot.c
@@ -10,6 +10,7 @@
 #include <console.h>
 #include <g_dnl.h>
 #include <fastboot.h>
+#include <getopt.h>
 #include <net.h>
 #include <usb.h>
 #include <watchdog.h>
@@ -126,41 +127,34 @@ exit:
 	return ret;
 }
 
-static int do_fastboot(struct cmd_tbl *cmdtp, int flag, int argc,
-		       char *const argv[])
+static int do_fastboot(struct getopt_state *gs)
 {
 	uintptr_t buf_addr = (uintptr_t)NULL;
 	size_t buf_size = 0;
+	int argc;
+	char *const *argv;
+	int opt;
 
-	if (argc < 2)
+	if (gs->argc < 2)
 		return CMD_RET_USAGE;
 
-	while (argc > 1 && **(argv + 1) == '-') {
-		char *arg = *++argv;
-
-		--argc;
-		while (*++arg) {
-			switch (*arg) {
-			case 'l':
-				if (--argc <= 0)
-					return CMD_RET_USAGE;
-				buf_addr = hextoul(*++argv, NULL);
-				goto NXTARG;
-
-			case 's':
-				if (--argc <= 0)
-					return CMD_RET_USAGE;
-				buf_size = hextoul(*++argv, NULL);
-				goto NXTARG;
-
-			default:
-				return CMD_RET_USAGE;
-			}
+	while ((opt = getopt(gs, "+l:s:")) > 0) {
+		switch (opt) {
+		case 'l':
+			buf_addr = hextoul(gs->arg, NULL);
+			break;
+		case 's':
+			buf_size = hextoul(gs->arg, NULL);
+			break;
+		default:
+			return CMD_RET_USAGE;
 		}
-NXTARG:
-		;
 	}
 
+	/* Step past the parsed options to the transport/controller args */
+	argc = gs->argc - (gs->index - 1);
+	argv = &gs->argv[gs->index - 1];
+
 	/* Handle case when USB controller param is just '-' */
 	if (argc == 1) {
 		pr_err("Error: Incorrect USB controller index\n");
@@ -183,7 +177,7 @@ NXTARG:
 	return do_fastboot_usb(argc, argv, buf_addr, buf_size);
 }
 
-U_BOOT_CMD(
+U_BOOT_CMD_GETOPT(
 	fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot,
 	"run as a fastboot usb or udp device",
 	"[-l addr] [-s size] usb <controller> | udp\n"
-- 
2.43.0



More information about the U-Boot mailing list