diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-06 11:33:07 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-06 11:33:07 +0000 |
commit | b0a6478eefe3894d16a15f8a23908135e7c97aa7 (patch) | |
tree | f519b80ccd92bef9bbf4d9f66d363d70107b0cd4 | |
parent | c8d27334a0921d6ca76862e9c7befe12a4df6dc6 (diff) | |
download | busybox-w32-b0a6478eefe3894d16a15f8a23908135e7c97aa7.tar.gz busybox-w32-b0a6478eefe3894d16a15f8a23908135e7c97aa7.tar.bz2 busybox-w32-b0a6478eefe3894d16a15f8a23908135e7c97aa7.zip |
hush: fix "export a=a b=b" (was not setting and exporting b)
function old new delta
builtin_export 103 117 +14
-rw-r--r-- | shell/hush.c | 59 |
1 files changed, 31 insertions, 28 deletions
diff --git a/shell/hush.c b/shell/hush.c index 119518bd1..3cf651b33 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -5442,8 +5442,8 @@ static int builtin_eval(char **argv) | |||
5442 | { | 5442 | { |
5443 | int rcode = EXIT_SUCCESS; | 5443 | int rcode = EXIT_SUCCESS; |
5444 | 5444 | ||
5445 | if (argv[1]) { | 5445 | if (*++argv) { |
5446 | char *str = expand_strvec_to_string(argv + 1); | 5446 | char *str = expand_strvec_to_string(argv); |
5447 | /* bash: | 5447 | /* bash: |
5448 | * eval "echo Hi; done" ("done" is syntax error): | 5448 | * eval "echo Hi; done" ("done" is syntax error): |
5449 | * "echo Hi" will not execute too. | 5449 | * "echo Hi" will not execute too. |
@@ -5458,13 +5458,14 @@ static int builtin_eval(char **argv) | |||
5458 | static int builtin_cd(char **argv) | 5458 | static int builtin_cd(char **argv) |
5459 | { | 5459 | { |
5460 | const char *newdir; | 5460 | const char *newdir; |
5461 | if (argv[1] == NULL) { | 5461 | if (*++argv == NULL) { |
5462 | /* bash does nothing (exitcode 0) if HOME is ""; if it's unset, | 5462 | /* bash does nothing (exitcode 0) if HOME is ""; if it's unset, |
5463 | * bash says "bash: cd: HOME not set" and does nothing (exitcode 1) | 5463 | * bash says "bash: cd: HOME not set" and does nothing (exitcode 1) |
5464 | */ | 5464 | */ |
5465 | newdir = getenv("HOME") ? : "/"; | 5465 | newdir = getenv("HOME") ? : "/"; |
5466 | } else | 5466 | } else { |
5467 | newdir = argv[1]; | 5467 | newdir = *argv; |
5468 | } | ||
5468 | if (chdir(newdir)) { | 5469 | if (chdir(newdir)) { |
5469 | printf("cd: %s: %s\n", newdir, strerror(errno)); | 5470 | printf("cd: %s: %s\n", newdir, strerror(errno)); |
5470 | return EXIT_FAILURE; | 5471 | return EXIT_FAILURE; |
@@ -5475,14 +5476,14 @@ static int builtin_cd(char **argv) | |||
5475 | 5476 | ||
5476 | static int builtin_exec(char **argv) | 5477 | static int builtin_exec(char **argv) |
5477 | { | 5478 | { |
5478 | if (argv[1] == NULL) | 5479 | if (*++argv == NULL) |
5479 | return EXIT_SUCCESS; /* bash does this */ | 5480 | return EXIT_SUCCESS; /* bash does this */ |
5480 | { | 5481 | { |
5481 | #if !BB_MMU | 5482 | #if !BB_MMU |
5482 | nommu_save_t dummy; | 5483 | nommu_save_t dummy; |
5483 | #endif | 5484 | #endif |
5484 | // FIXME: if exec fails, bash does NOT exit! We do... | 5485 | // FIXME: if exec fails, bash does NOT exit! We do... |
5485 | pseudo_exec_argv(&dummy, argv + 1, 0, NULL); | 5486 | pseudo_exec_argv(&dummy, argv, 0, NULL); |
5486 | /* never returns */ | 5487 | /* never returns */ |
5487 | } | 5488 | } |
5488 | } | 5489 | } |
@@ -5493,20 +5494,17 @@ static int builtin_exit(char **argv) | |||
5493 | //puts("exit"); /* bash does it */ | 5494 | //puts("exit"); /* bash does it */ |
5494 | // TODO: warn if we have background jobs: "There are stopped jobs" | 5495 | // TODO: warn if we have background jobs: "There are stopped jobs" |
5495 | // On second consecutive 'exit', exit anyway. | 5496 | // On second consecutive 'exit', exit anyway. |
5496 | if (argv[1] == NULL) | 5497 | if (*++argv == NULL) |
5497 | hush_exit(G.last_return_code); | 5498 | hush_exit(G.last_return_code); |
5498 | /* mimic bash: exit 123abc == exit 255 + error msg */ | 5499 | /* mimic bash: exit 123abc == exit 255 + error msg */ |
5499 | xfunc_error_retval = 255; | 5500 | xfunc_error_retval = 255; |
5500 | /* bash: exit -2 == exit 254, no error msg */ | 5501 | /* bash: exit -2 == exit 254, no error msg */ |
5501 | hush_exit(xatoi(argv[1]) & 0xff); | 5502 | hush_exit(xatoi(*argv) & 0xff); |
5502 | } | 5503 | } |
5503 | 5504 | ||
5504 | static int builtin_export(char **argv) | 5505 | static int builtin_export(char **argv) |
5505 | { | 5506 | { |
5506 | const char *value; | 5507 | if (*++argv == NULL) { |
5507 | char *name = argv[1]; | ||
5508 | |||
5509 | if (name == NULL) { | ||
5510 | // TODO: | 5508 | // TODO: |
5511 | // ash emits: export VAR='VAL' | 5509 | // ash emits: export VAR='VAL' |
5512 | // bash: declare -x VAR="VAL" | 5510 | // bash: declare -x VAR="VAL" |
@@ -5518,23 +5516,28 @@ static int builtin_export(char **argv) | |||
5518 | return EXIT_SUCCESS; | 5516 | return EXIT_SUCCESS; |
5519 | } | 5517 | } |
5520 | 5518 | ||
5521 | value = strchr(name, '='); | 5519 | do { |
5522 | if (!value) { | 5520 | const char *value; |
5523 | /* They are exporting something without a =VALUE */ | 5521 | char *name = *argv; |
5524 | struct variable *var; | 5522 | |
5525 | 5523 | value = strchr(name, '='); | |
5526 | var = get_local_var(name); | 5524 | if (!value) { |
5527 | if (var) { | 5525 | /* They are exporting something without a =VALUE */ |
5528 | var->flg_export = 1; | 5526 | struct variable *var; |
5529 | debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr); | 5527 | |
5530 | putenv(var->varstr); | 5528 | var = get_local_var(name); |
5529 | if (var) { | ||
5530 | var->flg_export = 1; | ||
5531 | debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr); | ||
5532 | putenv(var->varstr); | ||
5533 | } | ||
5534 | /* bash does not return an error when trying to export | ||
5535 | * an undefined variable. Do likewise. */ | ||
5536 | continue; | ||
5531 | } | 5537 | } |
5532 | /* bash does not return an error when trying to export | 5538 | set_local_var(xstrdup(name), 1, 0); |
5533 | * an undefined variable. Do likewise. */ | 5539 | } while (*++argv); |
5534 | return EXIT_SUCCESS; | ||
5535 | } | ||
5536 | 5540 | ||
5537 | set_local_var(xstrdup(name), 1, 0); | ||
5538 | return EXIT_SUCCESS; | 5541 | return EXIT_SUCCESS; |
5539 | } | 5542 | } |
5540 | 5543 | ||