aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-05-22 19:05:18 +0000
committerEric Andersen <andersen@codepoet.org>2001-05-22 19:05:18 +0000
commit94ac244dea54fca088b12665bc5862875c43e8c2 (patch)
treed0c5b6b4897035700f1957dffc4db6c5d18a8ba7
parent1eb4acfc2399d3ab4a7a122a0aff3f5d5109bf2c (diff)
downloadbusybox-w32-94ac244dea54fca088b12665bc5862875c43e8c2.tar.gz
busybox-w32-94ac244dea54fca088b12665bc5862875c43e8c2.tar.bz2
busybox-w32-94ac244dea54fca088b12665bc5862875c43e8c2.zip
Updates from both Vladimir and Larry
-rw-r--r--hush.c153
-rw-r--r--shell/hush.c153
2 files changed, 178 insertions, 128 deletions
diff --git a/hush.c b/hush.c
index 722dcf7ac..2b100983e 100644
--- a/hush.c
+++ b/hush.c
@@ -256,10 +256,8 @@ static const char *cwd;
256static struct jobset *job_list; 256static struct jobset *job_list;
257static unsigned int last_bg_pid; 257static unsigned int last_bg_pid;
258static char *PS1; 258static char *PS1;
259static char PS2[] = "> "; 259static char *PS2;
260
261struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 }; 260struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 };
262
263struct variables *top_vars = &shell_ver; 261struct variables *top_vars = &shell_ver;
264 262
265#define B_CHUNK (100) 263#define B_CHUNK (100)
@@ -505,29 +503,29 @@ static int builtin_export(struct child_prog *child)
505 name = strdup(name); 503 name = strdup(name);
506 504
507 if(name) { 505 if(name) {
508 char *value = strchr(name, '='); 506 char *value = strchr(name, '=');
509 507
510 if (!value) { 508 if (!value) {
511 char *tmp; 509 char *tmp;
512 /* They are exporting something without an =VALUE */ 510 /* They are exporting something without an =VALUE */
513 511
514 value = get_local_var(name); 512 value = get_local_var(name);
515 if (value) { 513 if (value) {
516 size_t ln = strlen(name); 514 size_t ln = strlen(name);
517 515
518 tmp = realloc(name, ln+strlen(value)+2); 516 tmp = realloc(name, ln+strlen(value)+2);
519 if(tmp==NULL) 517 if(tmp==NULL)
520 res = -1; 518 res = -1;
521 else { 519 else {
522 sprintf(tmp+ln, "=%s", value); 520 sprintf(tmp+ln, "=%s", value);
523 name = tmp; 521 name = tmp;
522 }
523 } else {
524 /* bash does not return an error when trying to export
525 * an undefined variable. Do likewise. */
526 res = 1;
524 } 527 }
525 } else {
526 /* bash not put error and set error code
527 if exporting not defined variable */
528 res = 1;
529 } 528 }
530 }
531 } 529 }
532 if (res<0) 530 if (res<0)
533 perror_msg("export"); 531 perror_msg("export");
@@ -641,7 +639,7 @@ static int builtin_read(struct child_prog *child)
641 char string[BUFSIZ]; 639 char string[BUFSIZ];
642 char *var = 0; 640 char *var = 0;
643 641
644 string[0] = 0; /* for correct work if stdin have "only EOF" */ 642 string[0] = 0; /* In case stdin has only EOF */
645 /* read string */ 643 /* read string */
646 fgets(string, sizeof(string), stdin); 644 fgets(string, sizeof(string), stdin);
647 chomp(string); 645 chomp(string);
@@ -650,10 +648,10 @@ static int builtin_read(struct child_prog *child)
650 sprintf(var, "%s=%s", child->argv[1], string); 648 sprintf(var, "%s=%s", child->argv[1], string);
651 res = set_local_var(var, 0); 649 res = set_local_var(var, 0);
652 } else 650 } else
653 res = -1; 651 res = -1;
654 if (res) 652 if (res)
655 fprintf(stderr, "read: %m\n"); 653 fprintf(stderr, "read: %m\n");
656 free(var); /* not move up - saved errno */ 654 free(var); /* So not move up to avoid breaking errno */
657 return res; 655 return res;
658 } else { 656 } else {
659 do res=getchar(); while(res!='\n' && res!=EOF); 657 do res=getchar(); while(res!='\n' && res!=EOF);
@@ -1061,6 +1059,9 @@ static int pipe_wait(struct pipe *pi)
1061} 1059}
1062 1060
1063/* never returns */ 1061/* never returns */
1062/* XXX no exit() here. If you don't exec, use _exit instead.
1063 * The at_exit handlers apparently confuse the calling process,
1064 * in particular stdin handling. Not sure why? */
1064static void pseudo_exec(struct child_prog *child) 1065static void pseudo_exec(struct child_prog *child)
1065{ 1066{
1066 int i, rcode; 1067 int i, rcode;
@@ -1076,7 +1077,9 @@ static void pseudo_exec(struct child_prog *child)
1076 /* If a variable is assigned in a forest, and nobody listens, 1077 /* If a variable is assigned in a forest, and nobody listens,
1077 * was it ever really set? 1078 * was it ever really set?
1078 */ 1079 */
1079 if (child->argv[0] == NULL) exit(EXIT_SUCCESS); 1080 if (child->argv[0] == NULL) {
1081 _exit(EXIT_SUCCESS);
1082 }
1080 1083
1081 /* 1084 /*
1082 * Check if the command matches any of the builtins. 1085 * Check if the command matches any of the builtins.
@@ -1087,7 +1090,7 @@ static void pseudo_exec(struct child_prog *child)
1087 for (x = bltins; x->cmd; x++) { 1090 for (x = bltins; x->cmd; x++) {
1088 if (strcmp(child->argv[0], x->cmd) == 0 ) { 1091 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1089 debug_printf("builtin exec %s\n", child->argv[0]); 1092 debug_printf("builtin exec %s\n", child->argv[0]);
1090 exit(x->function(child)); 1093 _exit(x->function(child));
1091 } 1094 }
1092 } 1095 }
1093 1096
@@ -1128,18 +1131,18 @@ static void pseudo_exec(struct child_prog *child)
1128 debug_printf("exec of %s\n",child->argv[0]); 1131 debug_printf("exec of %s\n",child->argv[0]);
1129 execvp(child->argv[0],child->argv); 1132 execvp(child->argv[0],child->argv);
1130 perror_msg("couldn't exec: %s",child->argv[0]); 1133 perror_msg("couldn't exec: %s",child->argv[0]);
1131 exit(1); 1134 _exit(1);
1132 } else if (child->group) { 1135 } else if (child->group) {
1133 debug_printf("runtime nesting to group\n"); 1136 debug_printf("runtime nesting to group\n");
1134 interactive=0; /* crucial!!!! */ 1137 interactive=0; /* crucial!!!! */
1135 rcode = run_list_real(child->group); 1138 rcode = run_list_real(child->group);
1136 /* OK to leak memory by not calling run_list_test, 1139 /* OK to leak memory by not calling run_list_test,
1137 * since this process is about to exit */ 1140 * since this process is about to exit */
1138 exit(rcode); 1141 _exit(rcode);
1139 } else { 1142 } else {
1140 /* Can happen. See what bash does with ">foo" by itself. */ 1143 /* Can happen. See what bash does with ">foo" by itself. */
1141 debug_printf("trying to pseudo_exec null command\n"); 1144 debug_printf("trying to pseudo_exec null command\n");
1142 exit(EXIT_SUCCESS); 1145 _exit(EXIT_SUCCESS);
1143 } 1146 }
1144} 1147}
1145 1148
@@ -1713,23 +1716,29 @@ static int set_local_var(const char *s, int flg_export)
1713 } else { 1716 } else {
1714 *value++ = 0; 1717 *value++ = 0;
1715 1718
1716 for(cur = top_vars; cur; cur = cur->next) 1719 for(cur = top_vars; cur; cur = cur->next) {
1717 if(strcmp(cur->name, name)==0) 1720 if(strcmp(cur->name, name)==0)
1718 break; 1721 break;
1722 }
1719 1723
1720 if(cur) { 1724 if(cur) {
1721 if(strcmp(cur->value, value)==0) { 1725 if(strcmp(cur->value, value)==0) {
1722 result = cur->flg_export == flg_export; 1726 if(flg_export>0 && cur->flg_export==0)
1727 cur->flg_export=flg_export;
1728 else
1729 result++;
1723 } else { 1730 } else {
1724 if(cur->flg_read_only) { 1731 if(cur->flg_read_only) {
1725 result = -1; 1732 result = -1;
1726 error_msg("%s: readonly variable", name); 1733 error_msg("%s: readonly variable", name);
1727 } else { 1734 } else {
1735 if(flg_export>0 || cur->flg_export>1)
1736 cur->flg_export=1;
1728 free(cur->value); 1737 free(cur->value);
1729 cur->value = newval; 1738 cur->value = newval;
1730 newval = 0; /* protect free */ 1739 newval = 0; /* protect free */
1731 } 1740 }
1732 } 1741 }
1733 } else { 1742 } else {
1734 cur = malloc(sizeof(struct variables)); 1743 cur = malloc(sizeof(struct variables));
1735 if(cur==0) { 1744 if(cur==0) {
@@ -1738,10 +1747,9 @@ static int set_local_var(const char *s, int flg_export)
1738 cur->name = strdup(name); 1747 cur->name = strdup(name);
1739 if(cur->name == 0) { 1748 if(cur->name == 0) {
1740 free(cur); 1749 free(cur);
1741 result = -1; 1750 result = -1;
1742 } else { 1751 } else {
1743 struct variables *bottom = top_vars; 1752 struct variables *bottom = top_vars;
1744
1745 cur->value = newval; 1753 cur->value = newval;
1746 newval = 0; /* protect free */ 1754 newval = 0; /* protect free */
1747 cur->next = 0; 1755 cur->next = 0;
@@ -1749,16 +1757,16 @@ static int set_local_var(const char *s, int flg_export)
1749 cur->flg_read_only = 0; 1757 cur->flg_read_only = 0;
1750 while(bottom->next) bottom=bottom->next; 1758 while(bottom->next) bottom=bottom->next;
1751 bottom->next = cur; 1759 bottom->next = cur;
1760 }
1752 } 1761 }
1753 } 1762 }
1754 } 1763 }
1755 }
1756 1764
1757 if((result==0 && flg_export==1) || (result>0 && cur->flg_export>0)) { 1765 if(result==0 && cur->flg_export==1) {
1758 *(value-1) = '='; 1766 *(value-1) = '=';
1759 result = putenv(name); 1767 result = putenv(name);
1760 } else { 1768 } else {
1761 free(name); 1769 free(name);
1762 if(result>0) /* equivalent to previous set */ 1770 if(result>0) /* equivalent to previous set */
1763 result = 0; 1771 result = 0;
1764 } 1772 }
@@ -1771,14 +1779,16 @@ static void unset_local_var(const char *name)
1771 struct variables *cur; 1779 struct variables *cur;
1772 1780
1773 if (name) { 1781 if (name) {
1774 for (cur = top_vars; cur; cur=cur->next) 1782 for (cur = top_vars; cur; cur=cur->next) {
1775 if(strcmp(cur->name, name)==0) 1783 if(strcmp(cur->name, name)==0)
1776 break; 1784 break;
1785 }
1777 if(cur!=0) { 1786 if(cur!=0) {
1778 struct variables *next = top_vars; 1787 struct variables *next = top_vars;
1779 if(cur==next) 1788 if(cur->flg_read_only) {
1780 return; 1789 error_msg("%s: readonly variable", name);
1781 else { 1790 return;
1791 } else {
1782 if(cur->flg_export) 1792 if(cur->flg_export)
1783 unsetenv(cur->name); 1793 unsetenv(cur->name);
1784 free(cur->name); 1794 free(cur->name);
@@ -2103,9 +2113,9 @@ FILE *generate_stream_from_list(struct pipe *head)
2103#if 0 2113#if 0
2104#define SURROGATE "surrogate response" 2114#define SURROGATE "surrogate response"
2105 write(1,SURROGATE,sizeof(SURROGATE)); 2115 write(1,SURROGATE,sizeof(SURROGATE));
2106 exit(run_list(head)); 2116 _exit(run_list(head));
2107#else 2117#else
2108 exit(run_list_real(head)); /* leaks memory */ 2118 _exit(run_list_real(head)); /* leaks memory */
2109#endif 2119#endif
2110 } 2120 }
2111 debug_printf("forked child %d\n",pid); 2121 debug_printf("forked child %d\n",pid);
@@ -2531,18 +2541,43 @@ int shell_main(int argc, char **argv)
2531 struct jobset joblist_end = { NULL, NULL }; 2541 struct jobset joblist_end = { NULL, NULL };
2532 char **e = environ; 2542 char **e = environ;
2533 2543
2534 /* initialize globals */ 2544 /* FIXME */
2545 fprintf(stderr, "sizeof(map)=%d\n", sizeof(map));
2546
2547
2548 /* XXX what should these be while sourcing /etc/profile? */
2549 global_argc = argc;
2550 global_argv = argv;
2551
2552 /* (re?) initialize globals. Sometimes shell_main() ends up calling
2553 * shell_main(), therefore we cannot rely on the BSS to zero out this
2554 * stuff. Reset these to 0 every time. */
2555 ifs = NULL;
2556 memset(map,0,sizeof(map));
2557 fake_mode = 0;
2558 interactive = 0;
2559 close_me_head = NULL;
2560 last_bg_pid = 0;
2561
2562 /* Initialize some more globals to non-zero values */
2563 set_cwd();
2564 job_list = &joblist_end;
2565#ifdef BB_FEATURE_COMMAND_EDITING
2566 cmdedit_set_initial_prompt();
2567#else
2568 PS1 = NULL;
2569#endif
2570 PS2 = "> ";
2571
2572 /* initialize our shell local variables with the values
2573 * currently living in the environment */
2535 if (e) { 2574 if (e) {
2536 for (; *e; e++) 2575 for (; *e; e++)
2537 set_local_var(*e, 2); /* without call putenv() */ 2576 set_local_var(*e, 2); /* without call putenv() */
2538 } 2577 }
2539 job_list = &joblist_end;
2540 2578
2541 last_return_code=EXIT_SUCCESS; 2579 last_return_code=EXIT_SUCCESS;
2542 2580
2543 /* XXX what should these be while sourcing /etc/profile? */
2544 global_argc = argc;
2545 global_argv = argv;
2546 2581
2547 /* If we get started under a job aware app (like bash 2582 /* If we get started under a job aware app (like bash
2548 * for example), make sure we are now in charge so we 2583 * for example), make sure we are now in charge so we
@@ -2563,16 +2598,6 @@ int shell_main(int argc, char **argv)
2563 } 2598 }
2564 input=stdin; 2599 input=stdin;
2565 2600
2566 /* initialize the cwd -- this is never freed...*/
2567 cwd = xgetcwd(0);
2568 if (!cwd)
2569 cwd = unknown;
2570#ifdef BB_FEATURE_COMMAND_EDITING
2571 cmdedit_set_initial_prompt();
2572#else
2573 PS1 = NULL;
2574#endif
2575
2576 while ((opt = getopt(argc, argv, "c:xif")) > 0) { 2601 while ((opt = getopt(argc, argv, "c:xif")) > 0) {
2577 switch (opt) { 2602 switch (opt) {
2578 case 'c': 2603 case 'c':
diff --git a/shell/hush.c b/shell/hush.c
index 722dcf7ac..2b100983e 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -256,10 +256,8 @@ static const char *cwd;
256static struct jobset *job_list; 256static struct jobset *job_list;
257static unsigned int last_bg_pid; 257static unsigned int last_bg_pid;
258static char *PS1; 258static char *PS1;
259static char PS2[] = "> "; 259static char *PS2;
260
261struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 }; 260struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 };
262
263struct variables *top_vars = &shell_ver; 261struct variables *top_vars = &shell_ver;
264 262
265#define B_CHUNK (100) 263#define B_CHUNK (100)
@@ -505,29 +503,29 @@ static int builtin_export(struct child_prog *child)
505 name = strdup(name); 503 name = strdup(name);
506 504
507 if(name) { 505 if(name) {
508 char *value = strchr(name, '='); 506 char *value = strchr(name, '=');
509 507
510 if (!value) { 508 if (!value) {
511 char *tmp; 509 char *tmp;
512 /* They are exporting something without an =VALUE */ 510 /* They are exporting something without an =VALUE */
513 511
514 value = get_local_var(name); 512 value = get_local_var(name);
515 if (value) { 513 if (value) {
516 size_t ln = strlen(name); 514 size_t ln = strlen(name);
517 515
518 tmp = realloc(name, ln+strlen(value)+2); 516 tmp = realloc(name, ln+strlen(value)+2);
519 if(tmp==NULL) 517 if(tmp==NULL)
520 res = -1; 518 res = -1;
521 else { 519 else {
522 sprintf(tmp+ln, "=%s", value); 520 sprintf(tmp+ln, "=%s", value);
523 name = tmp; 521 name = tmp;
522 }
523 } else {
524 /* bash does not return an error when trying to export
525 * an undefined variable. Do likewise. */
526 res = 1;
524 } 527 }
525 } else {
526 /* bash not put error and set error code
527 if exporting not defined variable */
528 res = 1;
529 } 528 }
530 }
531 } 529 }
532 if (res<0) 530 if (res<0)
533 perror_msg("export"); 531 perror_msg("export");
@@ -641,7 +639,7 @@ static int builtin_read(struct child_prog *child)
641 char string[BUFSIZ]; 639 char string[BUFSIZ];
642 char *var = 0; 640 char *var = 0;
643 641
644 string[0] = 0; /* for correct work if stdin have "only EOF" */ 642 string[0] = 0; /* In case stdin has only EOF */
645 /* read string */ 643 /* read string */
646 fgets(string, sizeof(string), stdin); 644 fgets(string, sizeof(string), stdin);
647 chomp(string); 645 chomp(string);
@@ -650,10 +648,10 @@ static int builtin_read(struct child_prog *child)
650 sprintf(var, "%s=%s", child->argv[1], string); 648 sprintf(var, "%s=%s", child->argv[1], string);
651 res = set_local_var(var, 0); 649 res = set_local_var(var, 0);
652 } else 650 } else
653 res = -1; 651 res = -1;
654 if (res) 652 if (res)
655 fprintf(stderr, "read: %m\n"); 653 fprintf(stderr, "read: %m\n");
656 free(var); /* not move up - saved errno */ 654 free(var); /* So not move up to avoid breaking errno */
657 return res; 655 return res;
658 } else { 656 } else {
659 do res=getchar(); while(res!='\n' && res!=EOF); 657 do res=getchar(); while(res!='\n' && res!=EOF);
@@ -1061,6 +1059,9 @@ static int pipe_wait(struct pipe *pi)
1061} 1059}
1062 1060
1063/* never returns */ 1061/* never returns */
1062/* XXX no exit() here. If you don't exec, use _exit instead.
1063 * The at_exit handlers apparently confuse the calling process,
1064 * in particular stdin handling. Not sure why? */
1064static void pseudo_exec(struct child_prog *child) 1065static void pseudo_exec(struct child_prog *child)
1065{ 1066{
1066 int i, rcode; 1067 int i, rcode;
@@ -1076,7 +1077,9 @@ static void pseudo_exec(struct child_prog *child)
1076 /* If a variable is assigned in a forest, and nobody listens, 1077 /* If a variable is assigned in a forest, and nobody listens,
1077 * was it ever really set? 1078 * was it ever really set?
1078 */ 1079 */
1079 if (child->argv[0] == NULL) exit(EXIT_SUCCESS); 1080 if (child->argv[0] == NULL) {
1081 _exit(EXIT_SUCCESS);
1082 }
1080 1083
1081 /* 1084 /*
1082 * Check if the command matches any of the builtins. 1085 * Check if the command matches any of the builtins.
@@ -1087,7 +1090,7 @@ static void pseudo_exec(struct child_prog *child)
1087 for (x = bltins; x->cmd; x++) { 1090 for (x = bltins; x->cmd; x++) {
1088 if (strcmp(child->argv[0], x->cmd) == 0 ) { 1091 if (strcmp(child->argv[0], x->cmd) == 0 ) {
1089 debug_printf("builtin exec %s\n", child->argv[0]); 1092 debug_printf("builtin exec %s\n", child->argv[0]);
1090 exit(x->function(child)); 1093 _exit(x->function(child));
1091 } 1094 }
1092 } 1095 }
1093 1096
@@ -1128,18 +1131,18 @@ static void pseudo_exec(struct child_prog *child)
1128 debug_printf("exec of %s\n",child->argv[0]); 1131 debug_printf("exec of %s\n",child->argv[0]);
1129 execvp(child->argv[0],child->argv); 1132 execvp(child->argv[0],child->argv);
1130 perror_msg("couldn't exec: %s",child->argv[0]); 1133 perror_msg("couldn't exec: %s",child->argv[0]);
1131 exit(1); 1134 _exit(1);
1132 } else if (child->group) { 1135 } else if (child->group) {
1133 debug_printf("runtime nesting to group\n"); 1136 debug_printf("runtime nesting to group\n");
1134 interactive=0; /* crucial!!!! */ 1137 interactive=0; /* crucial!!!! */
1135 rcode = run_list_real(child->group); 1138 rcode = run_list_real(child->group);
1136 /* OK to leak memory by not calling run_list_test, 1139 /* OK to leak memory by not calling run_list_test,
1137 * since this process is about to exit */ 1140 * since this process is about to exit */
1138 exit(rcode); 1141 _exit(rcode);
1139 } else { 1142 } else {
1140 /* Can happen. See what bash does with ">foo" by itself. */ 1143 /* Can happen. See what bash does with ">foo" by itself. */
1141 debug_printf("trying to pseudo_exec null command\n"); 1144 debug_printf("trying to pseudo_exec null command\n");
1142 exit(EXIT_SUCCESS); 1145 _exit(EXIT_SUCCESS);
1143 } 1146 }
1144} 1147}
1145 1148
@@ -1713,23 +1716,29 @@ static int set_local_var(const char *s, int flg_export)
1713 } else { 1716 } else {
1714 *value++ = 0; 1717 *value++ = 0;
1715 1718
1716 for(cur = top_vars; cur; cur = cur->next) 1719 for(cur = top_vars; cur; cur = cur->next) {
1717 if(strcmp(cur->name, name)==0) 1720 if(strcmp(cur->name, name)==0)
1718 break; 1721 break;
1722 }
1719 1723
1720 if(cur) { 1724 if(cur) {
1721 if(strcmp(cur->value, value)==0) { 1725 if(strcmp(cur->value, value)==0) {
1722 result = cur->flg_export == flg_export; 1726 if(flg_export>0 && cur->flg_export==0)
1727 cur->flg_export=flg_export;
1728 else
1729 result++;
1723 } else { 1730 } else {
1724 if(cur->flg_read_only) { 1731 if(cur->flg_read_only) {
1725 result = -1; 1732 result = -1;
1726 error_msg("%s: readonly variable", name); 1733 error_msg("%s: readonly variable", name);
1727 } else { 1734 } else {
1735 if(flg_export>0 || cur->flg_export>1)
1736 cur->flg_export=1;
1728 free(cur->value); 1737 free(cur->value);
1729 cur->value = newval; 1738 cur->value = newval;
1730 newval = 0; /* protect free */ 1739 newval = 0; /* protect free */
1731 } 1740 }
1732 } 1741 }
1733 } else { 1742 } else {
1734 cur = malloc(sizeof(struct variables)); 1743 cur = malloc(sizeof(struct variables));
1735 if(cur==0) { 1744 if(cur==0) {
@@ -1738,10 +1747,9 @@ static int set_local_var(const char *s, int flg_export)
1738 cur->name = strdup(name); 1747 cur->name = strdup(name);
1739 if(cur->name == 0) { 1748 if(cur->name == 0) {
1740 free(cur); 1749 free(cur);
1741 result = -1; 1750 result = -1;
1742 } else { 1751 } else {
1743 struct variables *bottom = top_vars; 1752 struct variables *bottom = top_vars;
1744
1745 cur->value = newval; 1753 cur->value = newval;
1746 newval = 0; /* protect free */ 1754 newval = 0; /* protect free */
1747 cur->next = 0; 1755 cur->next = 0;
@@ -1749,16 +1757,16 @@ static int set_local_var(const char *s, int flg_export)
1749 cur->flg_read_only = 0; 1757 cur->flg_read_only = 0;
1750 while(bottom->next) bottom=bottom->next; 1758 while(bottom->next) bottom=bottom->next;
1751 bottom->next = cur; 1759 bottom->next = cur;
1760 }
1752 } 1761 }
1753 } 1762 }
1754 } 1763 }
1755 }
1756 1764
1757 if((result==0 && flg_export==1) || (result>0 && cur->flg_export>0)) { 1765 if(result==0 && cur->flg_export==1) {
1758 *(value-1) = '='; 1766 *(value-1) = '=';
1759 result = putenv(name); 1767 result = putenv(name);
1760 } else { 1768 } else {
1761 free(name); 1769 free(name);
1762 if(result>0) /* equivalent to previous set */ 1770 if(result>0) /* equivalent to previous set */
1763 result = 0; 1771 result = 0;
1764 } 1772 }
@@ -1771,14 +1779,16 @@ static void unset_local_var(const char *name)
1771 struct variables *cur; 1779 struct variables *cur;
1772 1780
1773 if (name) { 1781 if (name) {
1774 for (cur = top_vars; cur; cur=cur->next) 1782 for (cur = top_vars; cur; cur=cur->next) {
1775 if(strcmp(cur->name, name)==0) 1783 if(strcmp(cur->name, name)==0)
1776 break; 1784 break;
1785 }
1777 if(cur!=0) { 1786 if(cur!=0) {
1778 struct variables *next = top_vars; 1787 struct variables *next = top_vars;
1779 if(cur==next) 1788 if(cur->flg_read_only) {
1780 return; 1789 error_msg("%s: readonly variable", name);
1781 else { 1790 return;
1791 } else {
1782 if(cur->flg_export) 1792 if(cur->flg_export)
1783 unsetenv(cur->name); 1793 unsetenv(cur->name);
1784 free(cur->name); 1794 free(cur->name);
@@ -2103,9 +2113,9 @@ FILE *generate_stream_from_list(struct pipe *head)
2103#if 0 2113#if 0
2104#define SURROGATE "surrogate response" 2114#define SURROGATE "surrogate response"
2105 write(1,SURROGATE,sizeof(SURROGATE)); 2115 write(1,SURROGATE,sizeof(SURROGATE));
2106 exit(run_list(head)); 2116 _exit(run_list(head));
2107#else 2117#else
2108 exit(run_list_real(head)); /* leaks memory */ 2118 _exit(run_list_real(head)); /* leaks memory */
2109#endif 2119#endif
2110 } 2120 }
2111 debug_printf("forked child %d\n",pid); 2121 debug_printf("forked child %d\n",pid);
@@ -2531,18 +2541,43 @@ int shell_main(int argc, char **argv)
2531 struct jobset joblist_end = { NULL, NULL }; 2541 struct jobset joblist_end = { NULL, NULL };
2532 char **e = environ; 2542 char **e = environ;
2533 2543
2534 /* initialize globals */ 2544 /* FIXME */
2545 fprintf(stderr, "sizeof(map)=%d\n", sizeof(map));
2546
2547
2548 /* XXX what should these be while sourcing /etc/profile? */
2549 global_argc = argc;
2550 global_argv = argv;
2551
2552 /* (re?) initialize globals. Sometimes shell_main() ends up calling
2553 * shell_main(), therefore we cannot rely on the BSS to zero out this
2554 * stuff. Reset these to 0 every time. */
2555 ifs = NULL;
2556 memset(map,0,sizeof(map));
2557 fake_mode = 0;
2558 interactive = 0;
2559 close_me_head = NULL;
2560 last_bg_pid = 0;
2561
2562 /* Initialize some more globals to non-zero values */
2563 set_cwd();
2564 job_list = &joblist_end;
2565#ifdef BB_FEATURE_COMMAND_EDITING
2566 cmdedit_set_initial_prompt();
2567#else
2568 PS1 = NULL;
2569#endif
2570 PS2 = "> ";
2571
2572 /* initialize our shell local variables with the values
2573 * currently living in the environment */
2535 if (e) { 2574 if (e) {
2536 for (; *e; e++) 2575 for (; *e; e++)
2537 set_local_var(*e, 2); /* without call putenv() */ 2576 set_local_var(*e, 2); /* without call putenv() */
2538 } 2577 }
2539 job_list = &joblist_end;
2540 2578
2541 last_return_code=EXIT_SUCCESS; 2579 last_return_code=EXIT_SUCCESS;
2542 2580
2543 /* XXX what should these be while sourcing /etc/profile? */
2544 global_argc = argc;
2545 global_argv = argv;
2546 2581
2547 /* If we get started under a job aware app (like bash 2582 /* If we get started under a job aware app (like bash
2548 * for example), make sure we are now in charge so we 2583 * for example), make sure we are now in charge so we
@@ -2563,16 +2598,6 @@ int shell_main(int argc, char **argv)
2563 } 2598 }
2564 input=stdin; 2599 input=stdin;
2565 2600
2566 /* initialize the cwd -- this is never freed...*/
2567 cwd = xgetcwd(0);
2568 if (!cwd)
2569 cwd = unknown;
2570#ifdef BB_FEATURE_COMMAND_EDITING
2571 cmdedit_set_initial_prompt();
2572#else
2573 PS1 = NULL;
2574#endif
2575
2576 while ((opt = getopt(argc, argv, "c:xif")) > 0) { 2601 while ((opt = getopt(argc, argv, "c:xif")) > 0) {
2577 switch (opt) { 2602 switch (opt) {
2578 case 'c': 2603 case 'c':