diff options
author | Eric Andersen | 2001-05-23 22:18:35 +0000 |
---|---|---|
committer | Eric Andersen | 2001-05-23 22:18:35 +0000 |
commit | bf7df04ec131c2d72e39d3ff6f2f85be675f9370 (patch) | |
tree | 6efda07961cb3432794453bb3842f04f2898c8bc | |
parent | 77d9268892b0d9624ab95bb551cbfe7a745d2666 (diff) | |
download | busybox-bf7df04ec131c2d72e39d3ff6f2f85be675f9370.zip busybox-bf7df04ec131c2d72e39d3ff6f2f85be675f9370.tar.gz |
Fix a massive memory leak in the run_list_test() function.
Rename run_list_test() as free_pipe_list().
Rename run_pipe_test() as free_pipe().
-Erik
-rw-r--r-- | hush.c | 44 | ||||
-rw-r--r-- | shell/hush.c | 44 |
2 files changed, 22 insertions, 66 deletions
@@ -357,8 +357,8 @@ static void mark_closed(int fd); static void close_all(); /* "run" the final data structures: */ static char *indenter(int i); -static int run_list_test(struct pipe *head, int indent); -static int run_pipe_test(struct pipe *pi, int indent); +static int free_pipe_list(struct pipe *head, int indent); +static int free_pipe(struct pipe *pi, int indent); /* really run the final data structures: */ static int setup_redirects(struct child_prog *prog, int squirrel[]); static int pipe_wait(struct pipe *pi); @@ -395,7 +395,6 @@ static int parse_file_outer(FILE *f); static void checkjobs(); static void insert_bg_job(struct pipe *pi); static void remove_bg_job(struct pipe *pi); -static void free_pipe(struct pipe *pi); /* local variable support */ static char *get_local_var(const char *var); static void unset_local_var(const char *name); @@ -1138,7 +1137,7 @@ static void pseudo_exec(struct child_prog *child) debug_printf("runtime nesting to group\n"); interactive=0; /* crucial!!!! */ rcode = run_list_real(child->group); - /* OK to leak memory by not calling run_list_test, + /* OK to leak memory by not calling free_pipe_list, * since this process is about to exit */ _exit(rcode); } else { @@ -1203,30 +1202,10 @@ static void remove_bg_job(struct pipe *pi) prev_pipe->next = pi->next; } - free_pipe(pi); + free_pipe(pi, 0); free(pi); } -/* free up all memory from a pipe */ -static void free_pipe(struct pipe *pi) -{ - int i; - - for (i = 0; i < pi->num_progs; i++) { - free(pi->progs[i].argv); - if (pi->progs[i].redirects) - free(pi->progs[i].redirects); - } - if (pi->progs) - free(pi->progs); - if (pi->text) - free(pi->text); - if (pi->cmdbuf) - free(pi->cmdbuf); - memset(pi, 0, sizeof(struct pipe)); -} - - /* Checks to see if any background processes have exited -- if they have, figure out why and see if a job has completed */ static void checkjobs() @@ -1535,7 +1514,7 @@ static char *indenter(int i) } /* return code is the exit status of the pipe */ -static int run_pipe_test(struct pipe *pi, int indent) +static int free_pipe(struct pipe *pi, int indent) { char **p; struct child_prog *child; @@ -1554,7 +1533,7 @@ static int run_pipe_test(struct pipe *pi, int indent) child->argv=NULL; } else if (child->group) { final_printf("%s begin group (subshell:%d)\n",ind, child->subshell); - ret_code = run_list_test(child->group,indent+3); + ret_code = free_pipe_list(child->group,indent+3); final_printf("%s end group\n",ind); } else { final_printf("%s (nil)\n",ind); @@ -1577,15 +1556,14 @@ static int run_pipe_test(struct pipe *pi, int indent) return ret_code; } -static int run_list_test(struct pipe *head, int indent) +static int free_pipe_list(struct pipe *head, int indent) { int rcode=0; /* if list has no members */ struct pipe *pi, *next; char *ind = indenter(indent); for (pi=head; pi; pi=next) { - if (pi->num_progs == 0) break; final_printf("%s pipe reserved mode %d\n", ind, pi->r_mode); - rcode = run_pipe_test(pi, indent); + rcode = free_pipe(pi, indent); final_printf("%s pipe followup code %d\n", ind, pi->followup); next=pi->next; pi->next=NULL; @@ -1601,10 +1579,10 @@ static int run_list(struct pipe *pi) if (fake_mode==0) { rcode = run_list_real(pi); } - /* run_list_test has the side effect of clearing memory + /* free_pipe_list has the side effect of clearing memory * In the long run that function can be merged with run_list_real, * but doing that now would hobble the debugging effort. */ - run_list_test(pi,0); + free_pipe_list(pi,0); return rcode; } @@ -2142,7 +2120,7 @@ FILE *generate_stream_from_list(struct pipe *head) pf = fdopen(channel[0],"r"); debug_printf("pipe on FILE *%p\n",pf); #else - run_list_test(head,0); + free_pipe_list(head,0); pf=popen("echo surrogate response","r"); debug_printf("started fake pipe on FILE *%p\n",pf); #endif diff --git a/shell/hush.c b/shell/hush.c index 0dc2d62..57b85d1 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -357,8 +357,8 @@ static void mark_closed(int fd); static void close_all(); /* "run" the final data structures: */ static char *indenter(int i); -static int run_list_test(struct pipe *head, int indent); -static int run_pipe_test(struct pipe *pi, int indent); +static int free_pipe_list(struct pipe *head, int indent); +static int free_pipe(struct pipe *pi, int indent); /* really run the final data structures: */ static int setup_redirects(struct child_prog *prog, int squirrel[]); static int pipe_wait(struct pipe *pi); @@ -395,7 +395,6 @@ static int parse_file_outer(FILE *f); static void checkjobs(); static void insert_bg_job(struct pipe *pi); static void remove_bg_job(struct pipe *pi); -static void free_pipe(struct pipe *pi); /* local variable support */ static char *get_local_var(const char *var); static void unset_local_var(const char *name); @@ -1138,7 +1137,7 @@ static void pseudo_exec(struct child_prog *child) debug_printf("runtime nesting to group\n"); interactive=0; /* crucial!!!! */ rcode = run_list_real(child->group); - /* OK to leak memory by not calling run_list_test, + /* OK to leak memory by not calling free_pipe_list, * since this process is about to exit */ _exit(rcode); } else { @@ -1203,30 +1202,10 @@ static void remove_bg_job(struct pipe *pi) prev_pipe->next = pi->next; } - free_pipe(pi); + free_pipe(pi, 0); free(pi); } -/* free up all memory from a pipe */ -static void free_pipe(struct pipe *pi) -{ - int i; - - for (i = 0; i < pi->num_progs; i++) { - free(pi->progs[i].argv); - if (pi->progs[i].redirects) - free(pi->progs[i].redirects); - } - if (pi->progs) - free(pi->progs); - if (pi->text) - free(pi->text); - if (pi->cmdbuf) - free(pi->cmdbuf); - memset(pi, 0, sizeof(struct pipe)); -} - - /* Checks to see if any background processes have exited -- if they have, figure out why and see if a job has completed */ static void checkjobs() @@ -1535,7 +1514,7 @@ static char *indenter(int i) } /* return code is the exit status of the pipe */ -static int run_pipe_test(struct pipe *pi, int indent) +static int free_pipe(struct pipe *pi, int indent) { char **p; struct child_prog *child; @@ -1554,7 +1533,7 @@ static int run_pipe_test(struct pipe *pi, int indent) child->argv=NULL; } else if (child->group) { final_printf("%s begin group (subshell:%d)\n",ind, child->subshell); - ret_code = run_list_test(child->group,indent+3); + ret_code = free_pipe_list(child->group,indent+3); final_printf("%s end group\n",ind); } else { final_printf("%s (nil)\n",ind); @@ -1577,15 +1556,14 @@ static int run_pipe_test(struct pipe *pi, int indent) return ret_code; } -static int run_list_test(struct pipe *head, int indent) +static int free_pipe_list(struct pipe *head, int indent) { int rcode=0; /* if list has no members */ struct pipe *pi, *next; char *ind = indenter(indent); for (pi=head; pi; pi=next) { - if (pi->num_progs == 0) break; final_printf("%s pipe reserved mode %d\n", ind, pi->r_mode); - rcode = run_pipe_test(pi, indent); + rcode = free_pipe(pi, indent); final_printf("%s pipe followup code %d\n", ind, pi->followup); next=pi->next; pi->next=NULL; @@ -1601,10 +1579,10 @@ static int run_list(struct pipe *pi) if (fake_mode==0) { rcode = run_list_real(pi); } - /* run_list_test has the side effect of clearing memory + /* free_pipe_list has the side effect of clearing memory * In the long run that function can be merged with run_list_real, * but doing that now would hobble the debugging effort. */ - run_list_test(pi,0); + free_pipe_list(pi,0); return rcode; } @@ -2142,7 +2120,7 @@ FILE *generate_stream_from_list(struct pipe *head) pf = fdopen(channel[0],"r"); debug_printf("pipe on FILE *%p\n",pf); #else - run_list_test(head,0); + free_pipe_list(head,0); pf=popen("echo surrogate response","r"); debug_printf("started fake pipe on FILE *%p\n",pf); #endif |