aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-04-06 11:33:07 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-04-06 11:33:07 +0000
commitb0a6478eefe3894d16a15f8a23908135e7c97aa7 (patch)
treef519b80ccd92bef9bbf4d9f66d363d70107b0cd4
parentc8d27334a0921d6ca76862e9c7befe12a4df6dc6 (diff)
downloadbusybox-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.c59
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)
5458static int builtin_cd(char **argv) 5458static 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
5476static int builtin_exec(char **argv) 5477static 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
5504static int builtin_export(char **argv) 5505static 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