diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-05-22 21:37:48 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-05-22 21:37:48 +0000 |
commit | 9978576f15b5bc1a60543e24722584b36b574933 (patch) | |
tree | c1251e440e1546b0ab892c2f6b1974aa639beaea | |
parent | aeb44c4da620cd4ec1c4f1e4f15fb227ec4dc8dc (diff) | |
download | busybox-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.c | 107 | ||||
-rw-r--r-- | shell/hush.c | 107 |
2 files changed, 122 insertions, 92 deletions
@@ -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 | } |