aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-05-22 21:37:48 +0000
committerEric Andersen <andersen@codepoet.org>2001-05-22 21:37:48 +0000
commit9978576f15b5bc1a60543e24722584b36b574933 (patch)
treec1251e440e1546b0ab892c2f6b1974aa639beaea
parentaeb44c4da620cd4ec1c4f1e4f15fb227ec4dc8dc (diff)
downloadbusybox-w32-9978576f15b5bc1a60543e24722584b36b574933.tar.gz
busybox-w32-9978576f15b5bc1a60543e24722584b36b574933.tar.bz2
busybox-w32-9978576f15b5bc1a60543e24722584b36b574933.zip
Fix this case. No, really this time.
unset FOO export FOO=bar FOO=baz echo "global env: " `env | grep ^FOO` echo "local env: " `set | grep ^FOO` -Erik
-rw-r--r--hush.c107
-rw-r--r--shell/hush.c107
2 files changed, 122 insertions, 92 deletions
diff --git a/hush.c b/hush.c
index a26e2f6e3..f995f6f20 100644
--- a/hush.c
+++ b/hush.c
@@ -1243,8 +1243,10 @@ static void checkjobs()
1243 break; 1243 break;
1244 } 1244 }
1245 1245
1246 if(pi==NULL) 1246 if(pi==NULL) {
1247 return; 1247 debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
1248 continue;
1249 }
1248 1250
1249 if (WIFEXITED(status) || WIFSIGNALED(status)) { 1251 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1250 /* child exited */ 1252 /* child exited */
@@ -1352,7 +1354,24 @@ static int run_pipe_real(struct pipe *pi)
1352 if (i!=0 && child->argv[i]==NULL) { 1354 if (i!=0 && child->argv[i]==NULL) {
1353 /* assignments, but no command: set the local environment */ 1355 /* assignments, but no command: set the local environment */
1354 for (i=0; child->argv[i]!=NULL; i++) { 1356 for (i=0; child->argv[i]!=NULL; i++) {
1355 set_local_var(child->argv[i], 0); 1357
1358 /* Ok, this case is tricky. We have to decide if this is a
1359 * local variable, or an already exported variable. If it is
1360 * already exported, we have to export the new value. If it is
1361 * not exported, we need only set this as a local variable.
1362 * This junk is all to decide whether or not to export this
1363 * variable. */
1364 int export_me=0;
1365 char *name, *value;
1366 name = strdup(child->argv[i]);
1367 value = strchr(name, '=');
1368 if (value)
1369 *value=0;
1370 if ( get_local_var(name)) {
1371 export_me=1;
1372 }
1373 free(name);
1374 set_local_var(child->argv[i], export_me);
1356 } 1375 }
1357 return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */ 1376 return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */
1358 } 1377 }
@@ -1704,7 +1723,6 @@ static int set_local_var(const char *s, int flg_export)
1704 char *name, *value; 1723 char *name, *value;
1705 int result=0; 1724 int result=0;
1706 struct variables *cur; 1725 struct variables *cur;
1707 char *newval = 0;
1708 1726
1709 name=strdup(s); 1727 name=strdup(s);
1710 1728
@@ -1712,55 +1730,52 @@ static int set_local_var(const char *s, int flg_export)
1712 * NAME=VALUE format. So the first order of business is to 1730 * NAME=VALUE format. So the first order of business is to
1713 * split 's' on the '=' into 'name' and 'value' */ 1731 * split 's' on the '=' into 'name' and 'value' */
1714 value = strchr(name, '='); 1732 value = strchr(name, '=');
1715 if (value==0 || (newval = strdup(value+1))==0) { 1733 if (value==0 && ++value==0) {
1716 result = -1; 1734 free(name);
1717 } else { 1735 return -1;
1718 *value++ = 0; 1736 }
1737 *value++ = 0;
1719 1738
1720 for(cur = top_vars; cur; cur = cur->next) { 1739 for(cur = top_vars; cur; cur = cur->next) {
1721 if(strcmp(cur->name, name)==0) 1740 if(strcmp(cur->name, name)==0)
1722 break; 1741 break;
1723 } 1742 }
1724 1743
1725 if(cur) { 1744 if(cur) {
1726 if(strcmp(cur->value, value)==0) { 1745 if(strcmp(cur->value, value)==0) {
1727 if(flg_export>0 && cur->flg_export==0) 1746 if(flg_export>0 && cur->flg_export==0)
1728 cur->flg_export=flg_export; 1747 cur->flg_export=flg_export;
1729 else 1748 else
1730 result++; 1749 result++;
1731 free(newval); 1750 } else {
1751 if(cur->flg_read_only) {
1752 error_msg("%s: readonly variable", name);
1753 result = -1;
1732 } else { 1754 } else {
1733 if(cur->flg_read_only) { 1755 if(flg_export>0 || cur->flg_export>1)
1734 error_msg("%s: readonly variable", name); 1756 cur->flg_export=1;
1735 free(newval); 1757 free(cur->value);
1736 result = -1; 1758
1737 } else { 1759 cur->value = strdup(value);
1738 if(flg_export>0 || cur->flg_export>1)
1739 cur->flg_export=1;
1740 free(cur->value);
1741 cur->value = newval;
1742 }
1743 } 1760 }
1761 }
1762 } else {
1763 cur = malloc(sizeof(struct variables));
1764 if(!cur) {
1765 result = -1;
1744 } else { 1766 } else {
1745 cur = malloc(sizeof(struct variables)); 1767 cur->name = strdup(name);
1746 if(cur==0) { 1768 if(cur->name == 0) {
1747 free(newval); 1769 free(cur);
1748 result = -1; 1770 result = -1;
1749 } else { 1771 } else {
1750 cur->name = strdup(name); 1772 struct variables *bottom = top_vars;
1751 if(cur->name == 0) { 1773 cur->value = strdup(value);
1752 free(cur); 1774 cur->next = 0;
1753 free(newval); 1775 cur->flg_export = flg_export;
1754 result = -1; 1776 cur->flg_read_only = 0;
1755 } else { 1777 while(bottom->next) bottom=bottom->next;
1756 struct variables *bottom = top_vars; 1778 bottom->next = cur;
1757 cur->value = newval;
1758 cur->next = 0;
1759 cur->flg_export = flg_export;
1760 cur->flg_read_only = 0;
1761 while(bottom->next) bottom=bottom->next;
1762 bottom->next = cur;
1763 }
1764 } 1779 }
1765 } 1780 }
1766 } 1781 }
diff --git a/shell/hush.c b/shell/hush.c
index a26e2f6e3..f995f6f20 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -1243,8 +1243,10 @@ static void checkjobs()
1243 break; 1243 break;
1244 } 1244 }
1245 1245
1246 if(pi==NULL) 1246 if(pi==NULL) {
1247 return; 1247 debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
1248 continue;
1249 }
1248 1250
1249 if (WIFEXITED(status) || WIFSIGNALED(status)) { 1251 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1250 /* child exited */ 1252 /* child exited */
@@ -1352,7 +1354,24 @@ static int run_pipe_real(struct pipe *pi)
1352 if (i!=0 && child->argv[i]==NULL) { 1354 if (i!=0 && child->argv[i]==NULL) {
1353 /* assignments, but no command: set the local environment */ 1355 /* assignments, but no command: set the local environment */
1354 for (i=0; child->argv[i]!=NULL; i++) { 1356 for (i=0; child->argv[i]!=NULL; i++) {
1355 set_local_var(child->argv[i], 0); 1357
1358 /* Ok, this case is tricky. We have to decide if this is a
1359 * local variable, or an already exported variable. If it is
1360 * already exported, we have to export the new value. If it is
1361 * not exported, we need only set this as a local variable.
1362 * This junk is all to decide whether or not to export this
1363 * variable. */
1364 int export_me=0;
1365 char *name, *value;
1366 name = strdup(child->argv[i]);
1367 value = strchr(name, '=');
1368 if (value)
1369 *value=0;
1370 if ( get_local_var(name)) {
1371 export_me=1;
1372 }
1373 free(name);
1374 set_local_var(child->argv[i], export_me);
1356 } 1375 }
1357 return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */ 1376 return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */
1358 } 1377 }
@@ -1704,7 +1723,6 @@ static int set_local_var(const char *s, int flg_export)
1704 char *name, *value; 1723 char *name, *value;
1705 int result=0; 1724 int result=0;
1706 struct variables *cur; 1725 struct variables *cur;
1707 char *newval = 0;
1708 1726
1709 name=strdup(s); 1727 name=strdup(s);
1710 1728
@@ -1712,55 +1730,52 @@ static int set_local_var(const char *s, int flg_export)
1712 * NAME=VALUE format. So the first order of business is to 1730 * NAME=VALUE format. So the first order of business is to
1713 * split 's' on the '=' into 'name' and 'value' */ 1731 * split 's' on the '=' into 'name' and 'value' */
1714 value = strchr(name, '='); 1732 value = strchr(name, '=');
1715 if (value==0 || (newval = strdup(value+1))==0) { 1733 if (value==0 && ++value==0) {
1716 result = -1; 1734 free(name);
1717 } else { 1735 return -1;
1718 *value++ = 0; 1736 }
1737 *value++ = 0;
1719 1738
1720 for(cur = top_vars; cur; cur = cur->next) { 1739 for(cur = top_vars; cur; cur = cur->next) {
1721 if(strcmp(cur->name, name)==0) 1740 if(strcmp(cur->name, name)==0)
1722 break; 1741 break;
1723 } 1742 }
1724 1743
1725 if(cur) { 1744 if(cur) {
1726 if(strcmp(cur->value, value)==0) { 1745 if(strcmp(cur->value, value)==0) {
1727 if(flg_export>0 && cur->flg_export==0) 1746 if(flg_export>0 && cur->flg_export==0)
1728 cur->flg_export=flg_export; 1747 cur->flg_export=flg_export;
1729 else 1748 else
1730 result++; 1749 result++;
1731 free(newval); 1750 } else {
1751 if(cur->flg_read_only) {
1752 error_msg("%s: readonly variable", name);
1753 result = -1;
1732 } else { 1754 } else {
1733 if(cur->flg_read_only) { 1755 if(flg_export>0 || cur->flg_export>1)
1734 error_msg("%s: readonly variable", name); 1756 cur->flg_export=1;
1735 free(newval); 1757 free(cur->value);
1736 result = -1; 1758
1737 } else { 1759 cur->value = strdup(value);
1738 if(flg_export>0 || cur->flg_export>1)
1739 cur->flg_export=1;
1740 free(cur->value);
1741 cur->value = newval;
1742 }
1743 } 1760 }
1761 }
1762 } else {
1763 cur = malloc(sizeof(struct variables));
1764 if(!cur) {
1765 result = -1;
1744 } else { 1766 } else {
1745 cur = malloc(sizeof(struct variables)); 1767 cur->name = strdup(name);
1746 if(cur==0) { 1768 if(cur->name == 0) {
1747 free(newval); 1769 free(cur);
1748 result = -1; 1770 result = -1;
1749 } else { 1771 } else {
1750 cur->name = strdup(name); 1772 struct variables *bottom = top_vars;
1751 if(cur->name == 0) { 1773 cur->value = strdup(value);
1752 free(cur); 1774 cur->next = 0;
1753 free(newval); 1775 cur->flg_export = flg_export;
1754 result = -1; 1776 cur->flg_read_only = 0;
1755 } else { 1777 while(bottom->next) bottom=bottom->next;
1756 struct variables *bottom = top_vars; 1778 bottom->next = cur;
1757 cur->value = newval;
1758 cur->next = 0;
1759 cur->flg_export = flg_export;
1760 cur->flg_read_only = 0;
1761 while(bottom->next) bottom=bottom->next;
1762 bottom->next = cur;
1763 }
1764 } 1779 }
1765 } 1780 }
1766 } 1781 }