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
This commit is contained in:
45
hush.c
45
hush.c
@ -1243,8 +1243,10 @@ static void checkjobs()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pi==NULL)
|
if(pi==NULL) {
|
||||||
return;
|
debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (WIFEXITED(status) || WIFSIGNALED(status)) {
|
if (WIFEXITED(status) || WIFSIGNALED(status)) {
|
||||||
/* child exited */
|
/* child exited */
|
||||||
@ -1352,7 +1354,24 @@ static int run_pipe_real(struct pipe *pi)
|
|||||||
if (i!=0 && child->argv[i]==NULL) {
|
if (i!=0 && child->argv[i]==NULL) {
|
||||||
/* assignments, but no command: set the local environment */
|
/* assignments, but no command: set the local environment */
|
||||||
for (i=0; child->argv[i]!=NULL; i++) {
|
for (i=0; child->argv[i]!=NULL; i++) {
|
||||||
set_local_var(child->argv[i], 0);
|
|
||||||
|
/* Ok, this case is tricky. We have to decide if this is a
|
||||||
|
* local variable, or an already exported variable. If it is
|
||||||
|
* already exported, we have to export the new value. If it is
|
||||||
|
* not exported, we need only set this as a local variable.
|
||||||
|
* This junk is all to decide whether or not to export this
|
||||||
|
* variable. */
|
||||||
|
int export_me=0;
|
||||||
|
char *name, *value;
|
||||||
|
name = strdup(child->argv[i]);
|
||||||
|
value = strchr(name, '=');
|
||||||
|
if (value)
|
||||||
|
*value=0;
|
||||||
|
if ( get_local_var(name)) {
|
||||||
|
export_me=1;
|
||||||
|
}
|
||||||
|
free(name);
|
||||||
|
set_local_var(child->argv[i], export_me);
|
||||||
}
|
}
|
||||||
return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */
|
return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */
|
||||||
}
|
}
|
||||||
@ -1704,7 +1723,6 @@ static int set_local_var(const char *s, int flg_export)
|
|||||||
char *name, *value;
|
char *name, *value;
|
||||||
int result=0;
|
int result=0;
|
||||||
struct variables *cur;
|
struct variables *cur;
|
||||||
char *newval = 0;
|
|
||||||
|
|
||||||
name=strdup(s);
|
name=strdup(s);
|
||||||
|
|
||||||
@ -1712,9 +1730,10 @@ static int set_local_var(const char *s, int flg_export)
|
|||||||
* NAME=VALUE format. So the first order of business is to
|
* NAME=VALUE format. So the first order of business is to
|
||||||
* split 's' on the '=' into 'name' and 'value' */
|
* split 's' on the '=' into 'name' and 'value' */
|
||||||
value = strchr(name, '=');
|
value = strchr(name, '=');
|
||||||
if (value==0 || (newval = strdup(value+1))==0) {
|
if (value==0 && ++value==0) {
|
||||||
result = -1;
|
free(name);
|
||||||
} else {
|
return -1;
|
||||||
|
}
|
||||||
*value++ = 0;
|
*value++ = 0;
|
||||||
|
|
||||||
for(cur = top_vars; cur; cur = cur->next) {
|
for(cur = top_vars; cur; cur = cur->next) {
|
||||||
@ -1728,33 +1747,30 @@ static int set_local_var(const char *s, int flg_export)
|
|||||||
cur->flg_export=flg_export;
|
cur->flg_export=flg_export;
|
||||||
else
|
else
|
||||||
result++;
|
result++;
|
||||||
free(newval);
|
|
||||||
} else {
|
} else {
|
||||||
if(cur->flg_read_only) {
|
if(cur->flg_read_only) {
|
||||||
error_msg("%s: readonly variable", name);
|
error_msg("%s: readonly variable", name);
|
||||||
free(newval);
|
|
||||||
result = -1;
|
result = -1;
|
||||||
} else {
|
} else {
|
||||||
if(flg_export>0 || cur->flg_export>1)
|
if(flg_export>0 || cur->flg_export>1)
|
||||||
cur->flg_export=1;
|
cur->flg_export=1;
|
||||||
free(cur->value);
|
free(cur->value);
|
||||||
cur->value = newval;
|
|
||||||
|
cur->value = strdup(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cur = malloc(sizeof(struct variables));
|
cur = malloc(sizeof(struct variables));
|
||||||
if(cur==0) {
|
if(!cur) {
|
||||||
free(newval);
|
|
||||||
result = -1;
|
result = -1;
|
||||||
} else {
|
} else {
|
||||||
cur->name = strdup(name);
|
cur->name = strdup(name);
|
||||||
if(cur->name == 0) {
|
if(cur->name == 0) {
|
||||||
free(cur);
|
free(cur);
|
||||||
free(newval);
|
|
||||||
result = -1;
|
result = -1;
|
||||||
} else {
|
} else {
|
||||||
struct variables *bottom = top_vars;
|
struct variables *bottom = top_vars;
|
||||||
cur->value = newval;
|
cur->value = strdup(value);
|
||||||
cur->next = 0;
|
cur->next = 0;
|
||||||
cur->flg_export = flg_export;
|
cur->flg_export = flg_export;
|
||||||
cur->flg_read_only = 0;
|
cur->flg_read_only = 0;
|
||||||
@ -1763,7 +1779,6 @@ static int set_local_var(const char *s, int flg_export)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(result==0 && cur->flg_export==1) {
|
if(result==0 && cur->flg_export==1) {
|
||||||
*(value-1) = '=';
|
*(value-1) = '=';
|
||||||
|
45
shell/hush.c
45
shell/hush.c
@ -1243,8 +1243,10 @@ static void checkjobs()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pi==NULL)
|
if(pi==NULL) {
|
||||||
return;
|
debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (WIFEXITED(status) || WIFSIGNALED(status)) {
|
if (WIFEXITED(status) || WIFSIGNALED(status)) {
|
||||||
/* child exited */
|
/* child exited */
|
||||||
@ -1352,7 +1354,24 @@ static int run_pipe_real(struct pipe *pi)
|
|||||||
if (i!=0 && child->argv[i]==NULL) {
|
if (i!=0 && child->argv[i]==NULL) {
|
||||||
/* assignments, but no command: set the local environment */
|
/* assignments, but no command: set the local environment */
|
||||||
for (i=0; child->argv[i]!=NULL; i++) {
|
for (i=0; child->argv[i]!=NULL; i++) {
|
||||||
set_local_var(child->argv[i], 0);
|
|
||||||
|
/* Ok, this case is tricky. We have to decide if this is a
|
||||||
|
* local variable, or an already exported variable. If it is
|
||||||
|
* already exported, we have to export the new value. If it is
|
||||||
|
* not exported, we need only set this as a local variable.
|
||||||
|
* This junk is all to decide whether or not to export this
|
||||||
|
* variable. */
|
||||||
|
int export_me=0;
|
||||||
|
char *name, *value;
|
||||||
|
name = strdup(child->argv[i]);
|
||||||
|
value = strchr(name, '=');
|
||||||
|
if (value)
|
||||||
|
*value=0;
|
||||||
|
if ( get_local_var(name)) {
|
||||||
|
export_me=1;
|
||||||
|
}
|
||||||
|
free(name);
|
||||||
|
set_local_var(child->argv[i], export_me);
|
||||||
}
|
}
|
||||||
return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */
|
return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */
|
||||||
}
|
}
|
||||||
@ -1704,7 +1723,6 @@ static int set_local_var(const char *s, int flg_export)
|
|||||||
char *name, *value;
|
char *name, *value;
|
||||||
int result=0;
|
int result=0;
|
||||||
struct variables *cur;
|
struct variables *cur;
|
||||||
char *newval = 0;
|
|
||||||
|
|
||||||
name=strdup(s);
|
name=strdup(s);
|
||||||
|
|
||||||
@ -1712,9 +1730,10 @@ static int set_local_var(const char *s, int flg_export)
|
|||||||
* NAME=VALUE format. So the first order of business is to
|
* NAME=VALUE format. So the first order of business is to
|
||||||
* split 's' on the '=' into 'name' and 'value' */
|
* split 's' on the '=' into 'name' and 'value' */
|
||||||
value = strchr(name, '=');
|
value = strchr(name, '=');
|
||||||
if (value==0 || (newval = strdup(value+1))==0) {
|
if (value==0 && ++value==0) {
|
||||||
result = -1;
|
free(name);
|
||||||
} else {
|
return -1;
|
||||||
|
}
|
||||||
*value++ = 0;
|
*value++ = 0;
|
||||||
|
|
||||||
for(cur = top_vars; cur; cur = cur->next) {
|
for(cur = top_vars; cur; cur = cur->next) {
|
||||||
@ -1728,33 +1747,30 @@ static int set_local_var(const char *s, int flg_export)
|
|||||||
cur->flg_export=flg_export;
|
cur->flg_export=flg_export;
|
||||||
else
|
else
|
||||||
result++;
|
result++;
|
||||||
free(newval);
|
|
||||||
} else {
|
} else {
|
||||||
if(cur->flg_read_only) {
|
if(cur->flg_read_only) {
|
||||||
error_msg("%s: readonly variable", name);
|
error_msg("%s: readonly variable", name);
|
||||||
free(newval);
|
|
||||||
result = -1;
|
result = -1;
|
||||||
} else {
|
} else {
|
||||||
if(flg_export>0 || cur->flg_export>1)
|
if(flg_export>0 || cur->flg_export>1)
|
||||||
cur->flg_export=1;
|
cur->flg_export=1;
|
||||||
free(cur->value);
|
free(cur->value);
|
||||||
cur->value = newval;
|
|
||||||
|
cur->value = strdup(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cur = malloc(sizeof(struct variables));
|
cur = malloc(sizeof(struct variables));
|
||||||
if(cur==0) {
|
if(!cur) {
|
||||||
free(newval);
|
|
||||||
result = -1;
|
result = -1;
|
||||||
} else {
|
} else {
|
||||||
cur->name = strdup(name);
|
cur->name = strdup(name);
|
||||||
if(cur->name == 0) {
|
if(cur->name == 0) {
|
||||||
free(cur);
|
free(cur);
|
||||||
free(newval);
|
|
||||||
result = -1;
|
result = -1;
|
||||||
} else {
|
} else {
|
||||||
struct variables *bottom = top_vars;
|
struct variables *bottom = top_vars;
|
||||||
cur->value = newval;
|
cur->value = strdup(value);
|
||||||
cur->next = 0;
|
cur->next = 0;
|
||||||
cur->flg_export = flg_export;
|
cur->flg_export = flg_export;
|
||||||
cur->flg_read_only = 0;
|
cur->flg_read_only = 0;
|
||||||
@ -1763,7 +1779,6 @@ static int set_local_var(const char *s, int flg_export)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(result==0 && cur->flg_export==1) {
|
if(result==0 && cur->flg_export==1) {
|
||||||
*(value-1) = '=';
|
*(value-1) = '=';
|
||||||
|
Reference in New Issue
Block a user