aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-05-22 20:29:00 +0000
committerEric Andersen <andersen@codepoet.org>2001-05-22 20:29:00 +0000
commitaeb44c4da620cd4ec1c4f1e4f15fb227ec4dc8dc (patch)
tree34880ad3a23ca05ec02f5a53d00067d6270f703a /shell/hush.c
parent816867858b90485df6c304673cbd01d9664007b4 (diff)
downloadbusybox-aeb44c4da620cd4ec1c4f1e4f15fb227ec4dc8dc.tar.gz
Fix a race. Sometimes by the time we got to checkjobs(), the
pipe struct had already been freed. Return immediately if the pipe is NULL.
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 46f1a77bd..a26e2f6e3 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -1243,6 +1243,9 @@ static void checkjobs()
break;
}
+ if(pi==NULL)
+ return;
+
if (WIFEXITED(status) || WIFSIGNALED(status)) {
/* child exited */
pi->running_progs--;
@@ -1253,8 +1256,6 @@ static void checkjobs()
remove_bg_job(pi);
}
} else {
- if(pi==NULL)
- break;
/* child stopped */
pi->stopped_progs++;
pi->progs[prognum].is_stopped = 1;
@@ -1727,31 +1728,33 @@ static int set_local_var(const char *s, int flg_export)
cur->flg_export=flg_export;
else
result++;
+ free(newval);
} else {
if(cur->flg_read_only) {
- result = -1;
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;
- newval = 0; /* protect free */
}
}
} else {
cur = malloc(sizeof(struct variables));
if(cur==0) {
+ free(newval);
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;
- newval = 0; /* protect free */
cur->next = 0;
cur->flg_export = flg_export;
cur->flg_read_only = 0;
@@ -1770,7 +1773,6 @@ static int set_local_var(const char *s, int flg_export)
if(result>0) /* equivalent to previous set */
result = 0;
}
- free(newval);
return result;
}
@@ -2473,10 +2475,10 @@ void update_ifs_map(void)
* The map[] array only really needs two bits each, and on most machines
* that would be faster because of the reduced L1 cache footprint.
*/
- memset(map,0,sizeof(map)); /* most characters flow through always */
- mapset("\\$'\"`", 3); /* never flow through */
- mapset("<>;&|(){}#", 1); /* flow through if quoted */
- mapset(ifs, 2); /* also flow through if quoted */
+ memset(map,0,sizeof(map)); /* most characters flow through always */
+ mapset("\\$'\"`", 3); /* never flow through */
+ mapset("<>;&|(){}#", 1); /* flow through if quoted */
+ mapset(ifs, 2); /* also flow through if quoted */
}
/* most recursion does not come through here, the exeception is
@@ -2549,7 +2551,7 @@ int shell_main(int argc, char **argv)
* shell_main(), therefore we cannot rely on the BSS to zero out this
* stuff. Reset these to 0 every time. */
ifs = NULL;
- memset(map,0,sizeof(map));
+ /* map[] is taken care of with call to update_ifs_map() */
fake_mode = 0;
interactive = 0;
close_me_head = NULL;
@@ -2650,7 +2652,20 @@ int shell_main(int argc, char **argv)
opt = parse_file_outer(input);
#ifdef BB_FEATURE_CLEAN_UP
- fclose(input.file);
+ fclose(input);
+ if (cwd && cwd != unknown)
+ free((char*)cwd);
+ {
+ struct variables *cur, *tmp;
+ for(cur = top_vars; cur; cur = tmp) {
+ tmp = cur->next;
+ if (!cur->flg_read_only) {
+ free(cur->name);
+ free(cur->value);
+ free(cur);
+ }
+ }
+ }
#endif
final_return: