[U-Boot] [PATCH] cli: hush: Adjust 'run' command to run each line of the env var
Simon Glass
sjg at chromium.org
Tue Oct 7 21:59:43 CEST 2014
The run command treats each argument an an environment variable. It gets the
value of each variable and executes it as a command. If an environment
variable contains a newline and the hush cli is used, it is supposed to
execute each line one after the other.
Normally a newline signals to hush to exit - this is used in normal command
line entry - after a command is entered we want to return to allow the user
to enter the next one. But environment variables obviously need to execute
to completion.
Add a special case for the execution of environment variables which
continues when a newline is seen, and add a few tests to check this
behaviour.
Note: it's not impossible that this may cause regressions in other areas.
I can't think of a case but with any change of behaviour with limited test
coverage there is always a risk. From what I can tell this behaviour has
been around since at least U-Boot 2011.03, although this pre-dates sandbox
and I have not tested it on real hardware.
Reported-by: Wolfgang Denk <wd at denx.de>
Signed-off-by: Simon Glass <sjg at chromium.org>
---
common/cli.c | 9 ++++++---
common/cli_hush.c | 3 ++-
include/cli_hush.h | 1 +
include/command.h | 1 +
test/command_ut.c | 14 ++++++++++++++
5 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/common/cli.c b/common/cli.c
index 272b028..075ae9d 100644
--- a/common/cli.c
+++ b/common/cli.c
@@ -36,8 +36,11 @@ int run_command(const char *cmd, int flag)
return 0;
#else
- return parse_string_outer(cmd,
- FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
+ int hush_flags = FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP;
+
+ if (flag & CMD_FLAG_ENV)
+ hush_flags |= FLAG_CONT_ON_NEWLINE;
+ return parse_string_outer(cmd, hush_flags);
#endif
}
@@ -125,7 +128,7 @@ int do_run(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 1;
}
- if (run_command(arg, flag) != 0)
+ if (run_command(arg, flag | CMD_FLAG_ENV) != 0)
return 1;
}
return 0;
diff --git a/common/cli_hush.c b/common/cli_hush.c
index 38da5a0..2b654b7 100644
--- a/common/cli_hush.c
+++ b/common/cli_hush.c
@@ -3170,7 +3170,8 @@ static int parse_stream_outer(struct in_str *inp, int flag)
update_ifs_map();
if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) mapset((uchar *)";$&|", 0);
inp->promptmode=1;
- rcode = parse_stream(&temp, &ctx, inp, '\n');
+ rcode = parse_stream(&temp, &ctx, inp,
+ flag & FLAG_CONT_ON_NEWLINE ? -1 : '\n');
#ifdef __U_BOOT__
if (rcode == 1) flag_repeat = 0;
#endif
diff --git a/include/cli_hush.h b/include/cli_hush.h
index 4951eef..57c870d 100644
--- a/include/cli_hush.h
+++ b/include/cli_hush.h
@@ -11,6 +11,7 @@
#define FLAG_EXIT_FROM_LOOP 1
#define FLAG_PARSE_SEMICOLON (1 << 1) /* symbol ';' is special for parser */
#define FLAG_REPARSING (1 << 2) /* >=2nd pass */
+#define FLAG_CONT_ON_NEWLINE (1 << 3) /* continue when we see \n */
extern int u_boot_hush_start(void);
extern int parse_string_outer(const char *, int);
diff --git a/include/command.h b/include/command.h
index 6f06db1..bd3fc04 100644
--- a/include/command.h
+++ b/include/command.h
@@ -147,6 +147,7 @@ int cmd_process(int flag, int argc, char * const argv[],
*/
#define CMD_FLAG_REPEAT 0x0001 /* repeat last command */
#define CMD_FLAG_BOOTD 0x0002 /* command is from bootd */
+#define CMD_FLAG_ENV 0x0004 /* command is from the environment */
#ifdef CONFIG_AUTO_COMPLETE
# define _CMD_COMPLETE(x) x,
diff --git a/test/command_ut.c b/test/command_ut.c
index ae6466d..e136075 100644
--- a/test/command_ut.c
+++ b/test/command_ut.c
@@ -66,7 +66,21 @@ static int do_ut_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
assert(run_command_list("false", -1, 0) == 1);
assert(run_command_list("echo", -1, 0) == 0);
+ run_command("setenv foo 'setenv monty 1; setenv python 2'", 0);
+ run_command("run foo", 0);
+ assert(getenv("monty") != NULL);
+ assert(!strcmp("1", getenv("monty")));
+ assert(getenv("python") != NULL);
+ assert(!strcmp("2", getenv("python")));
+
#ifdef CONFIG_SYS_HUSH_PARSER
+ run_command("setenv foo 'setenv black 1\nsetenv adder 2'", 0);
+ run_command("run foo", 0);
+ assert(getenv("black") != NULL);
+ assert(!strcmp("1", getenv("black")));
+ assert(getenv("adder") != NULL);
+ assert(!strcmp("2", getenv("adder")));
+
/* Test the 'test' command */
#define HUSH_TEST(name, expr, expected_result) \
--
2.1.0.rc2.206.gedb03e5
More information about the U-Boot
mailing list