aboutsummaryrefslogtreecommitdiff
path: root/common/cli_hush_upstream.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/cli_hush_upstream.c')
-rw-r--r--common/cli_hush_upstream.c74
1 files changed, 69 insertions, 5 deletions
diff --git a/common/cli_hush_upstream.c b/common/cli_hush_upstream.c
index d410425..a421faa 100644
--- a/common/cli_hush_upstream.c
+++ b/common/cli_hush_upstream.c
@@ -3475,7 +3475,6 @@ static int o_get_last_ptr(o_string *o, int n)
return ((int)(uintptr_t)list[n-1]) + string_start;
}
-#ifndef __U_BOOT__
/*
* Globbing routines.
*
@@ -3730,8 +3729,10 @@ static int glob_needed(const char *s)
*/
static int perform_glob(o_string *o, int n)
{
+#ifndef __U_BOOT__
glob_t globdata;
int gr;
+#endif /* __U_BOOT__ */
char *pattern;
debug_printf_glob("start perform_glob: n:%d o->data:%p\n", n, o->data);
@@ -3740,13 +3741,16 @@ static int perform_glob(o_string *o, int n)
pattern = o->data + o_get_last_ptr(o, n);
debug_printf_glob("glob pattern '%s'\n", pattern);
if (!glob_needed(pattern)) {
+#ifndef __U_BOOT__
literal:
+#endif /* __U_BOOT__ */
/* unbackslash last string in o in place, fix length */
o->length = unbackslash(pattern) - o->data;
debug_printf_glob("glob pattern '%s' is literal\n", pattern);
return o_save_ptr_helper(o, n);
}
+#ifndef __U_BOOT__
memset(&globdata, 0, sizeof(globdata));
/* Can't use GLOB_NOCHECK: it does not unescape the string.
* If we glob "*.\*" and don't find anything, we need
@@ -3782,16 +3786,22 @@ static int perform_glob(o_string *o, int n)
if (DEBUG_GLOB)
debug_print_list("perform_glob returning", o, n);
return n;
+#else /* __U_BOOT__ */
+ /*
+ * NOTE We only use perform glob to call unbackslash to remove backslash
+ * from string once expanded.
+ * So, it seems OK to return this if no previous return was done.
+ */
+ return o_save_ptr_helper(o, n);
+#endif /* __U_BOOT__ */
}
-#endif /* !__U_BOOT__ */
#endif /* !HUSH_BRACE_EXPANSION */
/* If o->o_expflags & EXP_FLAG_GLOB, glob the string so far remembered.
* Otherwise, just finish current list[] and start new */
static int o_save_ptr(o_string *o, int n)
{
-#ifndef __U_BOOT__
if (o->o_expflags & EXP_FLAG_GLOB) {
/* If o->has_empty_slot, list[n] was already globbed
* (if it was requested back then when it was filled)
@@ -3799,7 +3809,6 @@ static int o_save_ptr(o_string *o, int n)
if (!o->has_empty_slot)
return perform_glob(o, n); /* o_save_ptr_helper is inside */
}
-#endif /* !__U_BOOT__ */
return o_save_ptr_helper(o, n);
}
@@ -7012,7 +7021,20 @@ static NOINLINE int expand_one_var(o_string *output, int n,
}
#endif /* !__U_BOOT__ */
default:
+#ifndef __U_BOOT__
val = get_local_var_value(var);
+#else /* __U_BOOT__ */
+ /*
+ * Environment variable set with setenv* have to be
+ * expanded.
+ * So, we first search if the variable exists in
+ * environment, if this is not the case, we default to
+ * local value.
+ */
+ val = env_get(var);
+ if (!val)
+ val = get_local_var_value(var);
+#endif /* __U_BOOT__ */
}
}
@@ -9948,7 +9970,30 @@ static NOINLINE int run_pipe(struct pipe *pi)
#endif /* !__U_BOOT__ */
command = &pi->cmds[cmd_no];
cmd_no++;
- if (command->argv) {
+
+#ifdef __U_BOOT__
+ /* Replace argv and argc by expanded if it exists. */
+ if (argv_expanded) {
+ /*
+ * We need to save a pointer to argv, we will restore it
+ * later, so it will be freed when pipe is freed.
+ */
+ argv = command->argv;
+
+ /*
+ * After expansion, there can be more or less argument, so we need to
+ * update argc, for example:
+ * - More arguments:
+ * foo='bar quuz'
+ * echo $foo
+ * - Less arguments:
+ * echo $foo (if foo was never set)
+ */
+ command->argc = list_size(argv_expanded);
+ command->argv = argv_expanded;
+ }
+#endif /* __U_BOOT__ */
+ if (command->argv) {
debug_printf_exec(": pipe member '%s' '%s'...\n",
command->argv[0], command->argv[1]);
} else {
@@ -10063,6 +10108,25 @@ static NOINLINE int run_pipe(struct pipe *pi)
rcode = cmd_process(G.do_repeat ? CMD_FLAG_REPEAT : 0,
command->argc, command->argv,
&(G.flag_repeat), NULL);
+
+ if (argv_expanded) {
+ /*
+ * expand_strvec_to_strvec() allocates memory to expand
+ * argv, we need to free it.
+ */
+ free(argv_expanded);
+
+ /*
+ * We also restore command->argv to its original value
+ * so no memory leak happens.
+ */
+ command->argv = argv;
+
+ /*
+ * NOTE argc exists only in U-Boot, so argv freeing does
+ * not rely on it as this code exists in BusyBox.
+ */
+ }
#endif /* __U_BOOT__ */
}