Signed-off-by: Sean Anderson <sean...@gmail.com>
---
common/cli_hush.c | 39 ++++++++++++++++++++++++++++---
common/cli_simple.c | 8 ++++++-
common/command.c | 3 +++
include/asm-generic/global_data.h | 4 ++++
4 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/common/cli_hush.c b/common/cli_hush.c
index 83329763c6..8fed7eb14e 100644
--- a/common/cli_hush.c
+++ b/common/cli_hush.c
@@ -475,6 +475,8 @@ static char *make_string(char **inp, int *nonnull);
static int handle_dollar(o_string *dest, struct p_context *ctx, struct
in_str *input);
#ifndef __U_BOOT__
static int parse_string(o_string *dest, struct p_context *ctx, const
char *src);
+#else
+static void update_ifs_map(void);
#endif
static int parse_stream(o_string *dest, struct p_context *ctx, struct
in_str *input0, int end_trigger);
/* setup: */
@@ -1673,6 +1675,10 @@ static int run_pipe_real(struct pipe *pi)
"'run' command\n", child->argv[i]);
return -1;
}
+ if (gd->cmd_result)
+ puts(gd->cmd_result);
+ free(gd->cmd_result);
+ gd->cmd_result = NULL;
/* Process the command */
return cmd_process(flag, child->argc - i, child->argv + i,
&flag_repeat, NULL);
@@ -2683,6 +2689,7 @@ FILE *generate_stream_from_list(struct pipe
*head)
#endif
return pf;
}
+#endif /* __U_BOOT__ */
/* this version hacked for testing purposes */
/* return code is exit status of the process that is run. */
@@ -2691,7 +2698,11 @@ static int process_command_subs(o_string *dest,
struct p_context *ctx, struct in
int retcode;
o_string result=NULL_O_STRING;
struct p_context inner;
+#ifdef __U_BOOT__
+ int list_retcode;
+#else
FILE *p;
+#endif
struct in_str pipe_str;
initialize_context(&inner);
@@ -2702,13 +2713,21 @@ static int process_command_subs(o_string *dest,
struct p_context *ctx, struct in
done_pipe(&inner, PIPE_SEQ);
b_free(&result);
+#ifdef __U_BOOT__
+ list_retcode = run_list_real(inner.list_head);
+ setup_string_in_str(&pipe_str, gd->cmd_result ?: "");
+ /* Restore the original map as best we can */
+ update_ifs_map();
+#else
p=generate_stream_from_list(inner.list_head);
if (p==NULL) return 1;
mark_open(fileno(p));
setup_file_in_str(&pipe_str, p);
+#endif
/* now send results of command back into original context */
retcode = parse_stream(dest, ctx, &pipe_str, '\0');
+#ifndef __U_BOOT__
/* XXX In case of a syntax error, should we try to kill the child?
* That would be tough to do right, so just read until EOF. */
if (retcode == 1) {
@@ -2723,12 +2742,18 @@ static int process_command_subs(o_string *dest,
struct p_context *ctx, struct in
* to the KISS philosophy of this program. */
mark_closed(fileno(p));
retcode=pclose(p);
+#else
+ free(gd->cmd_result);
+ gd->cmd_result = NULL;
+ retcode = list_retcode;
+#endif
free_pipe_list(inner.list_head,0);
debug_printf("pclosed, retcode=%d\n",retcode);
/* XXX this process fails to trim a single trailing newline */
return retcode;
}
+#ifndef __U_BOOT__
static int parse_group(o_string *dest, struct p_context *ctx,
struct in_str *input, int ch)
{
@@ -2896,11 +2921,11 @@ static int handle_dollar(o_string *dest, struct
p_context *ctx, struct in_str *i
}
b_addchr(dest, SPECIAL_VAR_SYMBOL);
break;
-#ifndef __U_BOOT__
case '(':
b_getch(input);
process_command_subs(dest, ctx, input, ')');
break;
+#ifndef __U_BOOT__
case '*':
sep[0]=ifs[0];
for (i=1; i<global_argc; i++) {
@@ -3165,7 +3190,7 @@ static void update_ifs_map(void)
mapset(subst, 3); /* never flow through */
}
mapset((uchar *)"\\$'\"", 3); /* never flow through */
- mapset((uchar *)";&|#", 1); /* flow through if quoted */
+ mapset((uchar *)";&|()#", 1); /* flow through if quoted */
#endif
mapset(ifs, 2); /* also flow through if quoted */
}
@@ -3185,7 +3210,8 @@ static int parse_stream_outer(struct in_str *inp,
int flag)
ctx.type = flag;
initialize_context(&ctx);
update_ifs_map();
- if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING))
mapset((uchar *)";$&|", 0);
+ if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING))
+ mapset((uchar *)";$&|()", 0);
inp->promptmode=1;
rcode = parse_stream(&temp, &ctx, inp,
flag & FLAG_CONT_ON_NEWLINE ? -1 : '\n');
@@ -3205,6 +3231,13 @@ static int parse_stream_outer(struct in_str
*inp, int flag)
run_list(ctx.list_head);
#else
code = run_list(ctx.list_head);
+
+ if (!(flag & FLAG_REPARSING) && gd->cmd_result) {
+ puts(gd->cmd_result);
+ free(gd->cmd_result);
+ gd->cmd_result = NULL;
+ }
+
if (code == -2) { /* exit */
b_free(&temp);
code = 0;
diff --git a/common/cli_simple.c b/common/cli_simple.c
index e80ba488a5..5df30d964f 100644
--- a/common/cli_simple.c
+++ b/common/cli_simple.c
@@ -15,14 +15,16 @@
#include <console.h>
#include <env.h>
#include <log.h>
+#include <malloc.h>
#include <linux/ctype.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#define DEBUG_PARSER 0 /* set to 1 to debug */
#define debug_parser(fmt, args...) \
debug_cond(DEBUG_PARSER, fmt, ##args)
-
int cli_simple_parse_line(char *line, char *argv[])
{
int nargs = 0;
@@ -257,6 +259,10 @@ int cli_simple_run_command(const char *cmd, int
flag)
if (cmd_process(flag, argc, argv, &repeatable, NULL))
rc = -1;
+ if (gd->cmd_result)
+ puts(gd->cmd_result);
+ free(gd->cmd_result);
+ gd->cmd_result = NULL;
/* Did the user stop this? */
if (had_ctrlc())
diff --git a/common/command.c b/common/command.c
index 3fe6791eda..952a8f00eb 100644
--- a/common/command.c
+++ b/common/command.c
@@ -588,6 +588,9 @@ enum command_ret_t cmd_process(int flag, int argc,
char *const argv[],
enum command_ret_t rc = CMD_RET_SUCCESS;
struct cmd_tbl *cmdtp;
+ /* Clear previous result */
+ assert(!gd->cmd_result);
+
#if defined(CONFIG_SYS_XTRACE)
char *xtrace;
diff --git a/include/asm-generic/global_data.h
b/include/asm-generic/global_data.h
index b6a9991fc9..85262d9566 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -453,6 +453,10 @@ struct global_data {
*/
char *smbios_version;
#endif
+ /**
+ * @cmd_result: Result of the current command
+ */
+ char *cmd_result;
};
/**