diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-05 14:09:14 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-05 14:09:14 +0200 |
commit | 929a41d5770c0531f037c2e7db25bf98f9029c9e (patch) | |
tree | ab4a79bd1784435b1bbc3488145e7129452b8cdc /shell/hush.c | |
parent | 4e1dc539e97300c44589eff8baffd12c95a13d5f (diff) | |
download | busybox-w32-929a41d5770c0531f037c2e7db25bf98f9029c9e.tar.gz busybox-w32-929a41d5770c0531f037c2e7db25bf98f9029c9e.tar.bz2 busybox-w32-929a41d5770c0531f037c2e7db25bf98f9029c9e.zip |
hush: less mind-bending set_vars_and_save_old()
function old new delta
run_pipe 1651 1701 +50
set_local_var 510 557 +47
pseudo_exec_argv 544 581 +37
redirect_and_varexp_helper 64 56 -8
set_vars_and_save_old 164 149 -15
unset_local_var 274 256 -18
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/3 up/down: 134/-41) Total: 93 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to '')
-rw-r--r-- | shell/hush.c | 172 |
1 files changed, 101 insertions, 71 deletions
diff --git a/shell/hush.c b/shell/hush.c index 4740929e8..24ae237d7 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -2140,19 +2140,10 @@ static int set_local_var(char *str, unsigned flags) | |||
2140 | unsigned local_lvl = (flags >> SETFLAG_VARLVL_SHIFT); | 2140 | unsigned local_lvl = (flags >> SETFLAG_VARLVL_SHIFT); |
2141 | 2141 | ||
2142 | eq_sign = strchr(str, '='); | 2142 | eq_sign = strchr(str, '='); |
2143 | if (!eq_sign) { /* not expected to ever happen? */ | 2143 | if (HUSH_DEBUG && !eq_sign) |
2144 | free(str); | 2144 | bb_error_msg_and_die("BUG in setvar"); |
2145 | return -1; | ||
2146 | } | ||
2147 | 2145 | ||
2148 | name_len = eq_sign - str + 1; /* including '=' */ | 2146 | name_len = eq_sign - str + 1; /* including '=' */ |
2149 | #if ENABLE_HUSH_LINENO_VAR | ||
2150 | if (G.lineno_var) { | ||
2151 | if (name_len == 7 && strncmp("LINENO", str, 6) == 0) | ||
2152 | G.lineno_var = NULL; | ||
2153 | } | ||
2154 | #endif | ||
2155 | |||
2156 | cur_pp = &G.top_var; | 2147 | cur_pp = &G.top_var; |
2157 | while ((cur = *cur_pp) != NULL) { | 2148 | while ((cur = *cur_pp) != NULL) { |
2158 | if (strncmp(cur->varstr, str, name_len) != 0) { | 2149 | if (strncmp(cur->varstr, str, name_len) != 0) { |
@@ -2175,19 +2166,6 @@ static int set_local_var(char *str, unsigned flags) | |||
2175 | *eq_sign = '='; | 2166 | *eq_sign = '='; |
2176 | } | 2167 | } |
2177 | if (cur->var_nest_level < local_lvl) { | 2168 | if (cur->var_nest_level < local_lvl) { |
2178 | /* New variable is local ("local VAR=VAL" or | ||
2179 | * "VAR=VAL cmd") | ||
2180 | * and existing one is global, or local | ||
2181 | * on a lower level that new one. | ||
2182 | * Remove and save old one: | ||
2183 | */ | ||
2184 | debug_printf_env("shadowing %s'%s'/%u by '%s'/%u\n", | ||
2185 | cur->flg_export ? "exported " : "", | ||
2186 | cur->varstr, cur->var_nest_level, str, local_lvl | ||
2187 | ); | ||
2188 | *cur_pp = cur->next; | ||
2189 | cur->next = *G.shadowed_vars_pp; | ||
2190 | *G.shadowed_vars_pp = cur; | ||
2191 | /* bash 3.2.33(1) and exported vars: | 2169 | /* bash 3.2.33(1) and exported vars: |
2192 | * # export z=z | 2170 | * # export z=z |
2193 | * # f() { local z=a; env | grep ^z; } | 2171 | * # f() { local z=a; env | grep ^z; } |
@@ -2198,6 +2176,31 @@ static int set_local_var(char *str, unsigned flags) | |||
2198 | */ | 2176 | */ |
2199 | if (cur->flg_export) | 2177 | if (cur->flg_export) |
2200 | flags |= SETFLAG_EXPORT; | 2178 | flags |= SETFLAG_EXPORT; |
2179 | /* New variable is local ("local VAR=VAL" or | ||
2180 | * "VAR=VAL cmd") | ||
2181 | * and existing one is global, or local | ||
2182 | * on a lower level that new one. | ||
2183 | * Remove it from global variable list: | ||
2184 | */ | ||
2185 | *cur_pp = cur->next; | ||
2186 | if (G.shadowed_vars_pp) { | ||
2187 | /* Save in "shadowed" list */ | ||
2188 | debug_printf_env("shadowing %s'%s'/%u by '%s'/%u\n", | ||
2189 | cur->flg_export ? "exported " : "", | ||
2190 | cur->varstr, cur->var_nest_level, str, local_lvl | ||
2191 | ); | ||
2192 | cur->next = *G.shadowed_vars_pp; | ||
2193 | *G.shadowed_vars_pp = cur; | ||
2194 | } else { | ||
2195 | /* Came from pseudo_exec_argv(), no need to save: delete it */ | ||
2196 | debug_printf_env("shadow-deleting %s'%s'/%u by '%s'/%u\n", | ||
2197 | cur->flg_export ? "exported " : "", | ||
2198 | cur->varstr, cur->var_nest_level, str, local_lvl | ||
2199 | ); | ||
2200 | if (cur->max_len == 0) /* allocated "VAR=VAL"? */ | ||
2201 | free_me = cur->varstr; /* then free it later */ | ||
2202 | free(cur); | ||
2203 | } | ||
2201 | break; | 2204 | break; |
2202 | } | 2205 | } |
2203 | 2206 | ||
@@ -2207,8 +2210,10 @@ static int set_local_var(char *str, unsigned flags) | |||
2207 | free(str); | 2210 | free(str); |
2208 | goto exp; | 2211 | goto exp; |
2209 | } | 2212 | } |
2213 | |||
2214 | /* Replace the value in the found "struct variable" */ | ||
2210 | if (cur->max_len != 0) { | 2215 | if (cur->max_len != 0) { |
2211 | if (cur->max_len >= strlen(str)) { | 2216 | if (cur->max_len >= strnlen(str, cur->max_len + 1)) { |
2212 | /* This one is from startup env, reuse space */ | 2217 | /* This one is from startup env, reuse space */ |
2213 | debug_printf_env("reusing startup env for '%s'\n", str); | 2218 | debug_printf_env("reusing startup env for '%s'\n", str); |
2214 | strcpy(cur->varstr, str); | 2219 | strcpy(cur->varstr, str); |
@@ -2244,13 +2249,6 @@ static int set_local_var(char *str, unsigned flags) | |||
2244 | #endif | 2249 | #endif |
2245 | if (flags & SETFLAG_EXPORT) | 2250 | if (flags & SETFLAG_EXPORT) |
2246 | cur->flg_export = 1; | 2251 | cur->flg_export = 1; |
2247 | if (name_len == 4 && cur->varstr[0] == 'P' && cur->varstr[1] == 'S') | ||
2248 | cmdedit_update_prompt(); | ||
2249 | #if ENABLE_HUSH_GETOPTS | ||
2250 | /* defoptindvar is a "OPTIND=..." constant string */ | ||
2251 | if (strncmp(cur->varstr, defoptindvar, 7) == 0) | ||
2252 | G.getopt_count = 0; | ||
2253 | #endif | ||
2254 | if (cur->flg_export) { | 2252 | if (cur->flg_export) { |
2255 | if (flags & SETFLAG_UNEXPORT) { | 2253 | if (flags & SETFLAG_UNEXPORT) { |
2256 | cur->flg_export = 0; | 2254 | cur->flg_export = 0; |
@@ -2265,6 +2263,23 @@ static int set_local_var(char *str, unsigned flags) | |||
2265 | } | 2263 | } |
2266 | } | 2264 | } |
2267 | free(free_me); | 2265 | free(free_me); |
2266 | |||
2267 | /* Handle special names */ | ||
2268 | if (name_len == 4 && cur->varstr[0] == 'P' && cur->varstr[1] == 'S') | ||
2269 | cmdedit_update_prompt(); | ||
2270 | else | ||
2271 | if ((ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS) && name_len == 7) { | ||
2272 | #if ENABLE_HUSH_LINENO_VAR | ||
2273 | if (G.lineno_var && strncmp(cur->varstr, "LINENO", 6) == 0) | ||
2274 | G.lineno_var = NULL; | ||
2275 | #endif | ||
2276 | #if ENABLE_HUSH_GETOPTS | ||
2277 | /* defoptindvar is a "OPTIND=..." constant string */ | ||
2278 | if (strncmp(cur->varstr, defoptindvar, 7) == 0) | ||
2279 | G.getopt_count = 0; | ||
2280 | #endif | ||
2281 | } | ||
2282 | |||
2268 | return 0; | 2283 | return 0; |
2269 | } | 2284 | } |
2270 | 2285 | ||
@@ -2282,14 +2297,16 @@ static int unset_local_var_len(const char *name, int name_len) | |||
2282 | if (!name) | 2297 | if (!name) |
2283 | return EXIT_SUCCESS; | 2298 | return EXIT_SUCCESS; |
2284 | 2299 | ||
2300 | if ((ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS) && name_len == 6) { | ||
2285 | #if ENABLE_HUSH_GETOPTS | 2301 | #if ENABLE_HUSH_GETOPTS |
2286 | if (name_len == 6 && strncmp(name, "OPTIND", 6) == 0) | 2302 | if (strncmp(name, "OPTIND", 6) == 0) |
2287 | G.getopt_count = 0; | 2303 | G.getopt_count = 0; |
2288 | #endif | 2304 | #endif |
2289 | #if ENABLE_HUSH_LINENO_VAR | 2305 | #if ENABLE_HUSH_LINENO_VAR |
2290 | if (name_len == 6 && G.lineno_var && strncmp(name, "LINENO", 6) == 0) | 2306 | if (G.lineno_var && strncmp(name, "LINENO", 6) == 0) |
2291 | G.lineno_var = NULL; | 2307 | G.lineno_var = NULL; |
2292 | #endif | 2308 | #endif |
2309 | } | ||
2293 | 2310 | ||
2294 | cur_pp = &G.top_var; | 2311 | cur_pp = &G.top_var; |
2295 | while ((cur = *cur_pp) != NULL) { | 2312 | while ((cur = *cur_pp) != NULL) { |
@@ -2355,13 +2372,12 @@ static void add_vars(struct variable *var) | |||
2355 | * which attempts to overwrite it. | 2372 | * which attempts to overwrite it. |
2356 | * The strings[] vector itself is freed. | 2373 | * The strings[] vector itself is freed. |
2357 | */ | 2374 | */ |
2358 | static struct variable *set_vars_and_save_old(char **strings) | 2375 | static void set_vars_and_save_old(char **strings) |
2359 | { | 2376 | { |
2360 | char **s; | 2377 | char **s; |
2361 | struct variable *old = NULL; | ||
2362 | 2378 | ||
2363 | if (!strings) | 2379 | if (!strings) |
2364 | return old; | 2380 | return; |
2365 | 2381 | ||
2366 | s = strings; | 2382 | s = strings; |
2367 | while (*s) { | 2383 | while (*s) { |
@@ -2389,12 +2405,10 @@ static struct variable *set_vars_and_save_old(char **strings) | |||
2389 | do { *p = p[1]; p++; } while (*p); | 2405 | do { *p = p[1]; p++; } while (*p); |
2390 | goto next; | 2406 | goto next; |
2391 | } | 2407 | } |
2392 | /* Remove variable from global linked list */ | 2408 | /* below, set_local_var() with nest level will |
2393 | debug_printf_env("%s: removing '%s'\n", __func__, var_p->varstr); | 2409 | * "shadow" (remove) this variable from |
2394 | *var_pp = var_p->next; | 2410 | * global linked list. |
2395 | /* Add it to returned list */ | 2411 | */ |
2396 | var_p->next = old; | ||
2397 | old = var_p; | ||
2398 | } | 2412 | } |
2399 | //bb_error_msg("G.var_nest_level:%d", G.var_nest_level); | 2413 | //bb_error_msg("G.var_nest_level:%d", G.var_nest_level); |
2400 | set_local_var(*s, (G.var_nest_level << SETFLAG_VARLVL_SHIFT) | SETFLAG_EXPORT); | 2414 | set_local_var(*s, (G.var_nest_level << SETFLAG_VARLVL_SHIFT) | SETFLAG_EXPORT); |
@@ -2405,7 +2419,6 @@ static struct variable *set_vars_and_save_old(char **strings) | |||
2405 | next: ; | 2419 | next: ; |
2406 | } | 2420 | } |
2407 | free(strings); | 2421 | free(strings); |
2408 | return old; | ||
2409 | } | 2422 | } |
2410 | 2423 | ||
2411 | 2424 | ||
@@ -7598,6 +7611,7 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save, | |||
7598 | char **argv_expanded) | 7611 | char **argv_expanded) |
7599 | { | 7612 | { |
7600 | const struct built_in_command *x; | 7613 | const struct built_in_command *x; |
7614 | struct variable **sv_shadowed; | ||
7601 | char **new_env; | 7615 | char **new_env; |
7602 | IF_HUSH_COMMAND(char opt_vV = 0;) | 7616 | IF_HUSH_COMMAND(char opt_vV = 0;) |
7603 | IF_HUSH_FUNCTIONS(const struct function *funcp;) | 7617 | IF_HUSH_FUNCTIONS(const struct function *funcp;) |
@@ -7614,13 +7628,14 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save, | |||
7614 | _exit(EXIT_SUCCESS); | 7628 | _exit(EXIT_SUCCESS); |
7615 | } | 7629 | } |
7616 | 7630 | ||
7631 | sv_shadowed = G.shadowed_vars_pp; | ||
7617 | #if BB_MMU | 7632 | #if BB_MMU |
7618 | set_vars_and_save_old(new_env); | 7633 | G.shadowed_vars_pp = NULL; /* "don't save, free them instead" */ |
7619 | /* we can destroy set_vars_and_save_old's return value, | ||
7620 | * to save memory */ | ||
7621 | #else | 7634 | #else |
7622 | nommu_save->old_vars = set_vars_and_save_old(new_env); | 7635 | G.shadowed_vars_pp = &nommu_save->old_vars; |
7623 | #endif | 7636 | #endif |
7637 | set_vars_and_save_old(new_env); | ||
7638 | G.shadowed_vars_pp = sv_shadowed; | ||
7624 | 7639 | ||
7625 | if (argv_expanded) { | 7640 | if (argv_expanded) { |
7626 | argv = argv_expanded; | 7641 | argv = argv_expanded; |
@@ -8181,7 +8196,6 @@ static int checkjobs_and_fg_shell(struct pipe *fg_pipe) | |||
8181 | redirect_and_varexp_helper(old_vars_p, command, squirrel) | 8196 | redirect_and_varexp_helper(old_vars_p, command, squirrel) |
8182 | #endif | 8197 | #endif |
8183 | static int redirect_and_varexp_helper( | 8198 | static int redirect_and_varexp_helper( |
8184 | struct variable **old_vars_p, | ||
8185 | struct command *command, | 8199 | struct command *command, |
8186 | struct squirrel **sqp, | 8200 | struct squirrel **sqp, |
8187 | char **argv_expanded) | 8201 | char **argv_expanded) |
@@ -8196,7 +8210,7 @@ static int redirect_and_varexp_helper( | |||
8196 | dump_cmd_in_x_mode(new_env); | 8210 | dump_cmd_in_x_mode(new_env); |
8197 | dump_cmd_in_x_mode(argv_expanded); | 8211 | dump_cmd_in_x_mode(argv_expanded); |
8198 | /* this takes ownership of new_env[i] elements, and frees new_env: */ | 8212 | /* this takes ownership of new_env[i] elements, and frees new_env: */ |
8199 | *old_vars_p = set_vars_and_save_old(new_env); | 8213 | set_vars_and_save_old(new_env); |
8200 | } | 8214 | } |
8201 | return rcode; | 8215 | return rcode; |
8202 | } | 8216 | } |
@@ -8288,6 +8302,7 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
8288 | const struct built_in_command *x; | 8302 | const struct built_in_command *x; |
8289 | IF_HUSH_FUNCTIONS(const struct function *funcp;) | 8303 | IF_HUSH_FUNCTIONS(const struct function *funcp;) |
8290 | IF_NOT_HUSH_FUNCTIONS(enum { funcp = 0 };) | 8304 | IF_NOT_HUSH_FUNCTIONS(enum { funcp = 0 };) |
8305 | struct variable **sv_shadowed; | ||
8291 | struct variable *old_vars; | 8306 | struct variable *old_vars; |
8292 | 8307 | ||
8293 | #if ENABLE_HUSH_LINENO_VAR | 8308 | #if ENABLE_HUSH_LINENO_VAR |
@@ -8338,13 +8353,11 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
8338 | 8353 | ||
8339 | /* Expand the rest into (possibly) many strings each */ | 8354 | /* Expand the rest into (possibly) many strings each */ |
8340 | #if defined(CMD_SINGLEWORD_NOGLOB) | 8355 | #if defined(CMD_SINGLEWORD_NOGLOB) |
8341 | if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) { | 8356 | if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) |
8342 | argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt); | 8357 | argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt); |
8343 | } else | 8358 | else |
8344 | #endif | 8359 | #endif |
8345 | { | ||
8346 | argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt); | 8360 | argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt); |
8347 | } | ||
8348 | 8361 | ||
8349 | /* if someone gives us an empty string: `cmd with empty output` */ | 8362 | /* if someone gives us an empty string: `cmd with empty output` */ |
8350 | //TODO: what about: var=EXPR `` >FILE ? will var be set? Will FILE be created? | 8363 | //TODO: what about: var=EXPR `` >FILE ? will var be set? Will FILE be created? |
@@ -8354,17 +8367,19 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
8354 | return G.last_exitcode; | 8367 | return G.last_exitcode; |
8355 | } | 8368 | } |
8356 | 8369 | ||
8357 | #if ENABLE_HUSH_FUNCTIONS | 8370 | old_vars = NULL; |
8371 | sv_shadowed = G.shadowed_vars_pp; | ||
8372 | |||
8358 | /* Check if argv[0] matches any functions (this goes before bltins) */ | 8373 | /* Check if argv[0] matches any functions (this goes before bltins) */ |
8359 | funcp = find_function(argv_expanded[0]); | 8374 | IF_HUSH_FUNCTIONS(funcp = find_function(argv_expanded[0]);) |
8360 | #endif | 8375 | IF_HUSH_FUNCTIONS(x = NULL;) |
8361 | x = NULL; | 8376 | IF_HUSH_FUNCTIONS(if (!funcp)) |
8362 | if (!funcp) | ||
8363 | x = find_builtin(argv_expanded[0]); | 8377 | x = find_builtin(argv_expanded[0]); |
8364 | if (x || funcp) { | 8378 | if (x || funcp) { |
8365 | if (x && x->b_function == builtin_exec && argv_expanded[1] == NULL) { | 8379 | if (x && x->b_function == builtin_exec && argv_expanded[1] == NULL) { |
8366 | debug_printf("exec with redirects only\n"); | 8380 | debug_printf("exec with redirects only\n"); |
8367 | rcode = setup_redirects(command, NULL); | 8381 | rcode = setup_redirects(command, NULL); |
8382 | //TODO: what about: var=EXPR exec >FILE ? will var be set? | ||
8368 | /* rcode=1 can be if redir file can't be opened */ | 8383 | /* rcode=1 can be if redir file can't be opened */ |
8369 | goto clean_up_and_ret1; | 8384 | goto clean_up_and_ret1; |
8370 | } | 8385 | } |
@@ -8373,9 +8388,22 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
8373 | * a=b true; env | grep ^a= | 8388 | * a=b true; env | grep ^a= |
8374 | */ | 8389 | */ |
8375 | enter_var_nest_level(); | 8390 | enter_var_nest_level(); |
8376 | rcode = redirect_and_varexp_helper(&old_vars, command, &squirrel, argv_expanded); | 8391 | /* Collect all variables "shadowed" by helper |
8392 | * (IOW: old vars overridden by "var1=val1 var2=val2 cmd..." syntax) | ||
8393 | * into old_vars list: | ||
8394 | */ | ||
8395 | G.shadowed_vars_pp = &old_vars; | ||
8396 | rcode = redirect_and_varexp_helper(command, &squirrel, argv_expanded); | ||
8377 | if (rcode == 0) { | 8397 | if (rcode == 0) { |
8378 | if (!funcp) { | 8398 | if (!funcp) { |
8399 | /* Do not collect *to old_vars list* vars shadowed | ||
8400 | * by e.g. "local VAR" builtin (collect them | ||
8401 | * in the previously nested list instead): | ||
8402 | * don't want them to be restored immediately | ||
8403 | * after "local" completes. | ||
8404 | */ | ||
8405 | G.shadowed_vars_pp = sv_shadowed; | ||
8406 | |||
8379 | debug_printf_exec(": builtin '%s' '%s'...\n", | 8407 | debug_printf_exec(": builtin '%s' '%s'...\n", |
8380 | x->b_cmd, argv_expanded[1]); | 8408 | x->b_cmd, argv_expanded[1]); |
8381 | fflush_all(); | 8409 | fflush_all(); |
@@ -8384,17 +8412,15 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
8384 | } | 8412 | } |
8385 | #if ENABLE_HUSH_FUNCTIONS | 8413 | #if ENABLE_HUSH_FUNCTIONS |
8386 | else { | 8414 | else { |
8387 | struct variable **sv = G.shadowed_vars_pp; | ||
8388 | /* Make "local" builtins in the called function | ||
8389 | * stash shadowed variables in old_vars list | ||
8390 | */ | ||
8391 | G.shadowed_vars_pp = &old_vars; | ||
8392 | |||
8393 | debug_printf_exec(": function '%s' '%s'...\n", | 8415 | debug_printf_exec(": function '%s' '%s'...\n", |
8394 | funcp->name, argv_expanded[1]); | 8416 | funcp->name, argv_expanded[1]); |
8395 | rcode = run_function(funcp, argv_expanded) & 0xff; | 8417 | rcode = run_function(funcp, argv_expanded) & 0xff; |
8396 | 8418 | /* | |
8397 | G.shadowed_vars_pp = sv; | 8419 | * But do collect *to old_vars list* vars shadowed |
8420 | * within function execution. To that end, restore | ||
8421 | * this pointer _after_ function run: | ||
8422 | */ | ||
8423 | G.shadowed_vars_pp = sv_shadowed; | ||
8398 | } | 8424 | } |
8399 | #endif | 8425 | #endif |
8400 | } | 8426 | } |
@@ -8405,7 +8431,11 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
8405 | goto must_fork; | 8431 | goto must_fork; |
8406 | 8432 | ||
8407 | enter_var_nest_level(); | 8433 | enter_var_nest_level(); |
8408 | rcode = redirect_and_varexp_helper(&old_vars, command, &squirrel, argv_expanded); | 8434 | /* Collect all variables "shadowed" by helper into old_vars list */ |
8435 | G.shadowed_vars_pp = &old_vars; | ||
8436 | rcode = redirect_and_varexp_helper(command, &squirrel, argv_expanded); | ||
8437 | G.shadowed_vars_pp = sv_shadowed; | ||
8438 | |||
8409 | if (rcode == 0) { | 8439 | if (rcode == 0) { |
8410 | debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", | 8440 | debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", |
8411 | argv_expanded[0], argv_expanded[1]); | 8441 | argv_expanded[0], argv_expanded[1]); |