mirror of
https://github.com/sheumann/hush.git
synced 2024-08-25 21:28:57 +00:00
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:
parent
aeb44c4da6
commit
9978576f15
111
hush.c
111
hush.c
@ -1243,8 +1243,10 @@ static void checkjobs()
|
||||
break;
|
||||
}
|
||||
|
||||
if(pi==NULL)
|
||||
return;
|
||||
if(pi==NULL) {
|
||||
debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (WIFEXITED(status) || WIFSIGNALED(status)) {
|
||||
/* child exited */
|
||||
@ -1352,7 +1354,24 @@ static int run_pipe_real(struct pipe *pi)
|
||||
if (i!=0 && child->argv[i]==NULL) {
|
||||
/* assignments, but no command: set the local environment */
|
||||
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 */
|
||||
}
|
||||
@ -1704,7 +1723,6 @@ static int set_local_var(const char *s, int flg_export)
|
||||
char *name, *value;
|
||||
int result=0;
|
||||
struct variables *cur;
|
||||
char *newval = 0;
|
||||
|
||||
name=strdup(s);
|
||||
|
||||
@ -1712,55 +1730,52 @@ static int set_local_var(const char *s, int flg_export)
|
||||
* NAME=VALUE format. So the first order of business is to
|
||||
* split 's' on the '=' into 'name' and 'value' */
|
||||
value = strchr(name, '=');
|
||||
if (value==0 || (newval = strdup(value+1))==0) {
|
||||
result = -1;
|
||||
} else {
|
||||
*value++ = 0;
|
||||
if (value==0 && ++value==0) {
|
||||
free(name);
|
||||
return -1;
|
||||
}
|
||||
*value++ = 0;
|
||||
|
||||
for(cur = top_vars; cur; cur = cur->next) {
|
||||
if(strcmp(cur->name, name)==0)
|
||||
break;
|
||||
}
|
||||
for(cur = top_vars; cur; cur = cur->next) {
|
||||
if(strcmp(cur->name, name)==0)
|
||||
break;
|
||||
}
|
||||
|
||||
if(cur) {
|
||||
if(strcmp(cur->value, value)==0) {
|
||||
if(flg_export>0 && cur->flg_export==0)
|
||||
cur->flg_export=flg_export;
|
||||
else
|
||||
result++;
|
||||
free(newval);
|
||||
} else {
|
||||
if(cur->flg_read_only) {
|
||||
error_msg("%s: readonly variable", name);
|
||||
free(newval);
|
||||
result = -1;
|
||||
} else {
|
||||
if(flg_export>0 || cur->flg_export>1)
|
||||
cur->flg_export=1;
|
||||
free(cur->value);
|
||||
cur->value = newval;
|
||||
}
|
||||
}
|
||||
if(cur) {
|
||||
if(strcmp(cur->value, value)==0) {
|
||||
if(flg_export>0 && cur->flg_export==0)
|
||||
cur->flg_export=flg_export;
|
||||
else
|
||||
result++;
|
||||
} else {
|
||||
cur = malloc(sizeof(struct variables));
|
||||
if(cur==0) {
|
||||
free(newval);
|
||||
if(cur->flg_read_only) {
|
||||
error_msg("%s: readonly variable", name);
|
||||
result = -1;
|
||||
} else {
|
||||
cur->name = strdup(name);
|
||||
if(cur->name == 0) {
|
||||
free(cur);
|
||||
free(newval);
|
||||
result = -1;
|
||||
} else {
|
||||
struct variables *bottom = top_vars;
|
||||
cur->value = newval;
|
||||
cur->next = 0;
|
||||
cur->flg_export = flg_export;
|
||||
cur->flg_read_only = 0;
|
||||
while(bottom->next) bottom=bottom->next;
|
||||
bottom->next = cur;
|
||||
}
|
||||
if(flg_export>0 || cur->flg_export>1)
|
||||
cur->flg_export=1;
|
||||
free(cur->value);
|
||||
|
||||
cur->value = strdup(value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cur = malloc(sizeof(struct variables));
|
||||
if(!cur) {
|
||||
result = -1;
|
||||
} else {
|
||||
cur->name = strdup(name);
|
||||
if(cur->name == 0) {
|
||||
free(cur);
|
||||
result = -1;
|
||||
} else {
|
||||
struct variables *bottom = top_vars;
|
||||
cur->value = strdup(value);
|
||||
cur->next = 0;
|
||||
cur->flg_export = flg_export;
|
||||
cur->flg_read_only = 0;
|
||||
while(bottom->next) bottom=bottom->next;
|
||||
bottom->next = cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
111
shell/hush.c
111
shell/hush.c
@ -1243,8 +1243,10 @@ static void checkjobs()
|
||||
break;
|
||||
}
|
||||
|
||||
if(pi==NULL)
|
||||
return;
|
||||
if(pi==NULL) {
|
||||
debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (WIFEXITED(status) || WIFSIGNALED(status)) {
|
||||
/* child exited */
|
||||
@ -1352,7 +1354,24 @@ static int run_pipe_real(struct pipe *pi)
|
||||
if (i!=0 && child->argv[i]==NULL) {
|
||||
/* assignments, but no command: set the local environment */
|
||||
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 */
|
||||
}
|
||||
@ -1704,7 +1723,6 @@ static int set_local_var(const char *s, int flg_export)
|
||||
char *name, *value;
|
||||
int result=0;
|
||||
struct variables *cur;
|
||||
char *newval = 0;
|
||||
|
||||
name=strdup(s);
|
||||
|
||||
@ -1712,55 +1730,52 @@ static int set_local_var(const char *s, int flg_export)
|
||||
* NAME=VALUE format. So the first order of business is to
|
||||
* split 's' on the '=' into 'name' and 'value' */
|
||||
value = strchr(name, '=');
|
||||
if (value==0 || (newval = strdup(value+1))==0) {
|
||||
result = -1;
|
||||
} else {
|
||||
*value++ = 0;
|
||||
if (value==0 && ++value==0) {
|
||||
free(name);
|
||||
return -1;
|
||||
}
|
||||
*value++ = 0;
|
||||
|
||||
for(cur = top_vars; cur; cur = cur->next) {
|
||||
if(strcmp(cur->name, name)==0)
|
||||
break;
|
||||
}
|
||||
for(cur = top_vars; cur; cur = cur->next) {
|
||||
if(strcmp(cur->name, name)==0)
|
||||
break;
|
||||
}
|
||||
|
||||
if(cur) {
|
||||
if(strcmp(cur->value, value)==0) {
|
||||
if(flg_export>0 && cur->flg_export==0)
|
||||
cur->flg_export=flg_export;
|
||||
else
|
||||
result++;
|
||||
free(newval);
|
||||
} else {
|
||||
if(cur->flg_read_only) {
|
||||
error_msg("%s: readonly variable", name);
|
||||
free(newval);
|
||||
result = -1;
|
||||
} else {
|
||||
if(flg_export>0 || cur->flg_export>1)
|
||||
cur->flg_export=1;
|
||||
free(cur->value);
|
||||
cur->value = newval;
|
||||
}
|
||||
}
|
||||
if(cur) {
|
||||
if(strcmp(cur->value, value)==0) {
|
||||
if(flg_export>0 && cur->flg_export==0)
|
||||
cur->flg_export=flg_export;
|
||||
else
|
||||
result++;
|
||||
} else {
|
||||
cur = malloc(sizeof(struct variables));
|
||||
if(cur==0) {
|
||||
free(newval);
|
||||
if(cur->flg_read_only) {
|
||||
error_msg("%s: readonly variable", name);
|
||||
result = -1;
|
||||
} else {
|
||||
cur->name = strdup(name);
|
||||
if(cur->name == 0) {
|
||||
free(cur);
|
||||
free(newval);
|
||||
result = -1;
|
||||
} else {
|
||||
struct variables *bottom = top_vars;
|
||||
cur->value = newval;
|
||||
cur->next = 0;
|
||||
cur->flg_export = flg_export;
|
||||
cur->flg_read_only = 0;
|
||||
while(bottom->next) bottom=bottom->next;
|
||||
bottom->next = cur;
|
||||
}
|
||||
if(flg_export>0 || cur->flg_export>1)
|
||||
cur->flg_export=1;
|
||||
free(cur->value);
|
||||
|
||||
cur->value = strdup(value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cur = malloc(sizeof(struct variables));
|
||||
if(!cur) {
|
||||
result = -1;
|
||||
} else {
|
||||
cur->name = strdup(name);
|
||||
if(cur->name == 0) {
|
||||
free(cur);
|
||||
result = -1;
|
||||
} else {
|
||||
struct variables *bottom = top_vars;
|
||||
cur->value = strdup(value);
|
||||
cur->next = 0;
|
||||
cur->flg_export = flg_export;
|
||||
cur->flg_read_only = 0;
|
||||
while(bottom->next) bottom=bottom->next;
|
||||
bottom->next = cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user