Skip to content

Commit

Permalink
cli: hush: Adjust 'run' command to run each line of the env var
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Simon Glass <[email protected]>
  • Loading branch information
sjg20 authored and trini committed Oct 27, 2014
1 parent 0cf8761 commit 87b6398
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 4 deletions.
9 changes: 6 additions & 3 deletions common/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion common/cli_hush.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions include/cli_hush.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions include/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
14 changes: 14 additions & 0 deletions test/command_ut.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down

0 comments on commit 87b6398

Please sign in to comment.