[U-Boot] [PATCH] Handle environment variables like commands

Stefano Babic sbabic at denx.de
Wed Oct 15 15:56:32 CEST 2008


The command interpreter checks always if an environment variable
for that name exists and in this case the content of the variable
is executed. It becomes possible to redefine all U-Boot commands.
A new "builtin" command is added to be able to run builtin U-boot commands
even if they are redefined.
For this reason, builtin is a reserved word an no environment
variable can be set with this name.

Signed-off-by : Stefano Babic <sbabic at denx.de>
---
 common/cmd_nvedit.c |    8 ++++++++
 common/hush.c       |    9 ++++++++-
 common/main.c       |   37 +++++++++++++++++++++++++++++++++++++
 tools/env/fw_env.c  |    8 ++++++++
 4 files changed, 61 insertions(+), 1 deletions(-)

diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 637d6c9..c6e4ec7 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -161,6 +161,14 @@ int _do_setenv (int flag, int argc, char *argv[])
 	}
 
 	/*
+	 * Check for reserved words
+	 */
+	if (strcmp(name, "builtin") == 0) {
+		printf ("## Error: builtin is a reserved word. You cannot set a variable with this name\n");
+		return 1;
+	}
+
+	/*
 	 * search if variable with this name already exists
 	 */
 	oldval = -1;
diff --git a/common/hush.c b/common/hush.c
index 093c428..bd7b223 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -1677,9 +1677,16 @@ static int run_pipe_real(struct pipe *pi)
 					child->argv[i]);
 				return -1;
 			}
-			/* Look up command in command table */
 
+			/* Check if exists a variable with that name, builtin is forbidden */
+			if ((strcmp (child->argv[i], "builtin") != 0) && (p = getenv (child->argv[i])) != NULL )  {
+				int rcode;
+				rcode = (parse_string_outer(p,
+			                    FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0);
+				return rcode;
+			}
 
+			/* Look up command in command table */
 			if ((cmdtp = find_cmd(child->argv[i])) == NULL) {
 				printf ("Unknown command '%s' - try 'help'\n", child->argv[i]);
 				return -1;	/* give up after bad command */
diff --git a/common/main.c b/common/main.c
index c06ea07..d2be2ac 100644
--- a/common/main.c
+++ b/common/main.c
@@ -1289,6 +1289,7 @@ int run_command (const char *cmd, int flag)
 	int argc, inquotes;
 	int repeatable = 1;
 	int rc = 0;
+	char *runenv;
 
 #ifdef DEBUG_PARSER
 	printf ("[RUN_COMMAND] cmd[%p]=\"", cmd);
@@ -1357,6 +1358,13 @@ int run_command (const char *cmd, int flag)
 			continue;
 		}
 
+		if ((strcmp (argv[0], "builtin") != 0) && ((runenv = getenv (argv[0])) != NULL ))  {
+			if (run_command(runenv,flag) == -1) {
+				rc = -1;
+			}
+			continue;
+		}
+
 		/* Look up command in command table */
 		if ((cmdtp = find_cmd(argv[0])) == NULL) {
 			printf ("Unknown command '%s' - try 'help'\n", argv[0]);
@@ -1433,3 +1441,32 @@ int do_run (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 	return 0;
 }
 #endif
+
+int do_builtin (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	int i;
+
+	if (argc < 2) {
+		printf ("Usage:\n%s\n", cmdtp->usage);
+		return 1;
+	}
+
+	/* Look up command in command table */
+	if ((cmdtp = find_cmd(argv[1])) == NULL) {
+		printf ("Unknown builtin command '%s' - try 'help'\n", argv[1]);
+		return 1;
+	}
+
+	/* Remove builtin from arg list */
+	argc--;
+
+	/* OK - call function to do the command */
+	if ((cmdtp->cmd) (cmdtp, flag, argc, &argv[1]) != 0) {
+		return 1;
+	}
+}
+
+U_BOOT_CMD(
+	builtin,	CFG_MAXARGS,	1,	do_builtin,
+	"builtin     - run builtin commands\n",
+);
diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c
index 6e9c34f..cc31b79 100644
--- a/tools/env/fw_env.c
+++ b/tools/env/fw_env.c
@@ -353,6 +353,14 @@ int fw_setenv (int argc, char *argv[])
 	name = argv[1];
 
 	/*
+	 * Check for reserved words
+	 */
+	if (strcmp(name, "builtin") == 0) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	/*
 	 * search if variable with this name already exists
 	 */
 	for (nxt = env = environment.data; *env; env = nxt + 1) {
-- 
1.5.4.3



More information about the U-Boot mailing list