aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-05-23 22:18:35 +0000
committerEric Andersen <andersen@codepoet.org>2001-05-23 22:18:35 +0000
commitbf7df04ec131c2d72e39d3ff6f2f85be675f9370 (patch)
tree6efda07961cb3432794453bb3842f04f2898c8bc
parent77d9268892b0d9624ab95bb551cbfe7a745d2666 (diff)
downloadbusybox-w32-bf7df04ec131c2d72e39d3ff6f2f85be675f9370.tar.gz
busybox-w32-bf7df04ec131c2d72e39d3ff6f2f85be675f9370.tar.bz2
busybox-w32-bf7df04ec131c2d72e39d3ff6f2f85be675f9370.zip
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.c44
-rw-r--r--shell/hush.c44
2 files changed, 22 insertions, 66 deletions
diff --git a/hush.c b/hush.c
index 0dc2d62f8..57b85d1bc 100644
--- a/hush.c
+++ b/hush.c
@@ -357,8 +357,8 @@ static void mark_closed(int fd);
357static void close_all(); 357static void close_all();
358/* "run" the final data structures: */ 358/* "run" the final data structures: */
359static char *indenter(int i); 359static char *indenter(int i);
360static int run_list_test(struct pipe *head, int indent); 360static int free_pipe_list(struct pipe *head, int indent);
361static int run_pipe_test(struct pipe *pi, int indent); 361static int free_pipe(struct pipe *pi, int indent);
362/* really run the final data structures: */ 362/* really run the final data structures: */
363static int setup_redirects(struct child_prog *prog, int squirrel[]); 363static int setup_redirects(struct child_prog *prog, int squirrel[]);
364static int pipe_wait(struct pipe *pi); 364static int pipe_wait(struct pipe *pi);
@@ -395,7 +395,6 @@ static int parse_file_outer(FILE *f);
395static void checkjobs(); 395static void checkjobs();
396static void insert_bg_job(struct pipe *pi); 396static void insert_bg_job(struct pipe *pi);
397static void remove_bg_job(struct pipe *pi); 397static void remove_bg_job(struct pipe *pi);
398static void free_pipe(struct pipe *pi);
399/* local variable support */ 398/* local variable support */
400static char *get_local_var(const char *var); 399static char *get_local_var(const char *var);
401static void unset_local_var(const char *name); 400static void unset_local_var(const char *name);
@@ -1138,7 +1137,7 @@ static void pseudo_exec(struct child_prog *child)
1138 debug_printf("runtime nesting to group\n"); 1137 debug_printf("runtime nesting to group\n");
1139 interactive=0; /* crucial!!!! */ 1138 interactive=0; /* crucial!!!! */
1140 rcode = run_list_real(child->group); 1139 rcode = run_list_real(child->group);
1141 /* OK to leak memory by not calling run_list_test, 1140 /* OK to leak memory by not calling free_pipe_list,
1142 * since this process is about to exit */ 1141 * since this process is about to exit */
1143 _exit(rcode); 1142 _exit(rcode);
1144 } else { 1143 } else {
@@ -1203,30 +1202,10 @@ static void remove_bg_job(struct pipe *pi)
1203 prev_pipe->next = pi->next; 1202 prev_pipe->next = pi->next;
1204 } 1203 }
1205 1204
1206 free_pipe(pi); 1205 free_pipe(pi, 0);
1207 free(pi); 1206 free(pi);
1208} 1207}
1209 1208
1210/* free up all memory from a pipe */
1211static void free_pipe(struct pipe *pi)
1212{
1213 int i;
1214
1215 for (i = 0; i < pi->num_progs; i++) {
1216 free(pi->progs[i].argv);
1217 if (pi->progs[i].redirects)
1218 free(pi->progs[i].redirects);
1219 }
1220 if (pi->progs)
1221 free(pi->progs);
1222 if (pi->text)
1223 free(pi->text);
1224 if (pi->cmdbuf)
1225 free(pi->cmdbuf);
1226 memset(pi, 0, sizeof(struct pipe));
1227}
1228
1229
1230/* Checks to see if any background processes have exited -- if they 1209/* Checks to see if any background processes have exited -- if they
1231 have, figure out why and see if a job has completed */ 1210 have, figure out why and see if a job has completed */
1232static void checkjobs() 1211static void checkjobs()
@@ -1535,7 +1514,7 @@ static char *indenter(int i)
1535} 1514}
1536 1515
1537/* return code is the exit status of the pipe */ 1516/* return code is the exit status of the pipe */
1538static int run_pipe_test(struct pipe *pi, int indent) 1517static int free_pipe(struct pipe *pi, int indent)
1539{ 1518{
1540 char **p; 1519 char **p;
1541 struct child_prog *child; 1520 struct child_prog *child;
@@ -1554,7 +1533,7 @@ static int run_pipe_test(struct pipe *pi, int indent)
1554 child->argv=NULL; 1533 child->argv=NULL;
1555 } else if (child->group) { 1534 } else if (child->group) {
1556 final_printf("%s begin group (subshell:%d)\n",ind, child->subshell); 1535 final_printf("%s begin group (subshell:%d)\n",ind, child->subshell);
1557 ret_code = run_list_test(child->group,indent+3); 1536 ret_code = free_pipe_list(child->group,indent+3);
1558 final_printf("%s end group\n",ind); 1537 final_printf("%s end group\n",ind);
1559 } else { 1538 } else {
1560 final_printf("%s (nil)\n",ind); 1539 final_printf("%s (nil)\n",ind);
@@ -1577,15 +1556,14 @@ static int run_pipe_test(struct pipe *pi, int indent)
1577 return ret_code; 1556 return ret_code;
1578} 1557}
1579 1558
1580static int run_list_test(struct pipe *head, int indent) 1559static int free_pipe_list(struct pipe *head, int indent)
1581{ 1560{
1582 int rcode=0; /* if list has no members */ 1561 int rcode=0; /* if list has no members */
1583 struct pipe *pi, *next; 1562 struct pipe *pi, *next;
1584 char *ind = indenter(indent); 1563 char *ind = indenter(indent);
1585 for (pi=head; pi; pi=next) { 1564 for (pi=head; pi; pi=next) {
1586 if (pi->num_progs == 0) break;
1587 final_printf("%s pipe reserved mode %d\n", ind, pi->r_mode); 1565 final_printf("%s pipe reserved mode %d\n", ind, pi->r_mode);
1588 rcode = run_pipe_test(pi, indent); 1566 rcode = free_pipe(pi, indent);
1589 final_printf("%s pipe followup code %d\n", ind, pi->followup); 1567 final_printf("%s pipe followup code %d\n", ind, pi->followup);
1590 next=pi->next; 1568 next=pi->next;
1591 pi->next=NULL; 1569 pi->next=NULL;
@@ -1601,10 +1579,10 @@ static int run_list(struct pipe *pi)
1601 if (fake_mode==0) { 1579 if (fake_mode==0) {
1602 rcode = run_list_real(pi); 1580 rcode = run_list_real(pi);
1603 } 1581 }
1604 /* run_list_test has the side effect of clearing memory 1582 /* free_pipe_list has the side effect of clearing memory
1605 * In the long run that function can be merged with run_list_real, 1583 * In the long run that function can be merged with run_list_real,
1606 * but doing that now would hobble the debugging effort. */ 1584 * but doing that now would hobble the debugging effort. */
1607 run_list_test(pi,0); 1585 free_pipe_list(pi,0);
1608 return rcode; 1586 return rcode;
1609} 1587}
1610 1588
@@ -2142,7 +2120,7 @@ FILE *generate_stream_from_list(struct pipe *head)
2142 pf = fdopen(channel[0],"r"); 2120 pf = fdopen(channel[0],"r");
2143 debug_printf("pipe on FILE *%p\n",pf); 2121 debug_printf("pipe on FILE *%p\n",pf);
2144#else 2122#else
2145 run_list_test(head,0); 2123 free_pipe_list(head,0);
2146 pf=popen("echo surrogate response","r"); 2124 pf=popen("echo surrogate response","r");
2147 debug_printf("started fake pipe on FILE *%p\n",pf); 2125 debug_printf("started fake pipe on FILE *%p\n",pf);
2148#endif 2126#endif
diff --git a/shell/hush.c b/shell/hush.c
index 0dc2d62f8..57b85d1bc 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -357,8 +357,8 @@ static void mark_closed(int fd);
357static void close_all(); 357static void close_all();
358/* "run" the final data structures: */ 358/* "run" the final data structures: */
359static char *indenter(int i); 359static char *indenter(int i);
360static int run_list_test(struct pipe *head, int indent); 360static int free_pipe_list(struct pipe *head, int indent);
361static int run_pipe_test(struct pipe *pi, int indent); 361static int free_pipe(struct pipe *pi, int indent);
362/* really run the final data structures: */ 362/* really run the final data structures: */
363static int setup_redirects(struct child_prog *prog, int squirrel[]); 363static int setup_redirects(struct child_prog *prog, int squirrel[]);
364static int pipe_wait(struct pipe *pi); 364static int pipe_wait(struct pipe *pi);
@@ -395,7 +395,6 @@ static int parse_file_outer(FILE *f);
395static void checkjobs(); 395static void checkjobs();
396static void insert_bg_job(struct pipe *pi); 396static void insert_bg_job(struct pipe *pi);
397static void remove_bg_job(struct pipe *pi); 397static void remove_bg_job(struct pipe *pi);
398static void free_pipe(struct pipe *pi);
399/* local variable support */ 398/* local variable support */
400static char *get_local_var(const char *var); 399static char *get_local_var(const char *var);
401static void unset_local_var(const char *name); 400static void unset_local_var(const char *name);
@@ -1138,7 +1137,7 @@ static void pseudo_exec(struct child_prog *child)
1138 debug_printf("runtime nesting to group\n"); 1137 debug_printf("runtime nesting to group\n");
1139 interactive=0; /* crucial!!!! */ 1138 interactive=0; /* crucial!!!! */
1140 rcode = run_list_real(child->group); 1139 rcode = run_list_real(child->group);
1141 /* OK to leak memory by not calling run_list_test, 1140 /* OK to leak memory by not calling free_pipe_list,
1142 * since this process is about to exit */ 1141 * since this process is about to exit */
1143 _exit(rcode); 1142 _exit(rcode);
1144 } else { 1143 } else {
@@ -1203,30 +1202,10 @@ static void remove_bg_job(struct pipe *pi)
1203 prev_pipe->next = pi->next; 1202 prev_pipe->next = pi->next;
1204 } 1203 }
1205 1204
1206 free_pipe(pi); 1205 free_pipe(pi, 0);
1207 free(pi); 1206 free(pi);
1208} 1207}
1209 1208
1210/* free up all memory from a pipe */
1211static void free_pipe(struct pipe *pi)
1212{
1213 int i;
1214
1215 for (i = 0; i < pi->num_progs; i++) {
1216 free(pi->progs[i].argv);
1217 if (pi->progs[i].redirects)
1218 free(pi->progs[i].redirects);
1219 }
1220 if (pi->progs)
1221 free(pi->progs);
1222 if (pi->text)
1223 free(pi->text);
1224 if (pi->cmdbuf)
1225 free(pi->cmdbuf);
1226 memset(pi, 0, sizeof(struct pipe));
1227}
1228
1229
1230/* Checks to see if any background processes have exited -- if they 1209/* Checks to see if any background processes have exited -- if they
1231 have, figure out why and see if a job has completed */ 1210 have, figure out why and see if a job has completed */
1232static void checkjobs() 1211static void checkjobs()
@@ -1535,7 +1514,7 @@ static char *indenter(int i)
1535} 1514}
1536 1515
1537/* return code is the exit status of the pipe */ 1516/* return code is the exit status of the pipe */
1538static int run_pipe_test(struct pipe *pi, int indent) 1517static int free_pipe(struct pipe *pi, int indent)
1539{ 1518{
1540 char **p; 1519 char **p;
1541 struct child_prog *child; 1520 struct child_prog *child;
@@ -1554,7 +1533,7 @@ static int run_pipe_test(struct pipe *pi, int indent)
1554 child->argv=NULL; 1533 child->argv=NULL;
1555 } else if (child->group) { 1534 } else if (child->group) {
1556 final_printf("%s begin group (subshell:%d)\n",ind, child->subshell); 1535 final_printf("%s begin group (subshell:%d)\n",ind, child->subshell);
1557 ret_code = run_list_test(child->group,indent+3); 1536 ret_code = free_pipe_list(child->group,indent+3);
1558 final_printf("%s end group\n",ind); 1537 final_printf("%s end group\n",ind);
1559 } else { 1538 } else {
1560 final_printf("%s (nil)\n",ind); 1539 final_printf("%s (nil)\n",ind);
@@ -1577,15 +1556,14 @@ static int run_pipe_test(struct pipe *pi, int indent)
1577 return ret_code; 1556 return ret_code;
1578} 1557}
1579 1558
1580static int run_list_test(struct pipe *head, int indent) 1559static int free_pipe_list(struct pipe *head, int indent)
1581{ 1560{
1582 int rcode=0; /* if list has no members */ 1561 int rcode=0; /* if list has no members */
1583 struct pipe *pi, *next; 1562 struct pipe *pi, *next;
1584 char *ind = indenter(indent); 1563 char *ind = indenter(indent);
1585 for (pi=head; pi; pi=next) { 1564 for (pi=head; pi; pi=next) {
1586 if (pi->num_progs == 0) break;
1587 final_printf("%s pipe reserved mode %d\n", ind, pi->r_mode); 1565 final_printf("%s pipe reserved mode %d\n", ind, pi->r_mode);
1588 rcode = run_pipe_test(pi, indent); 1566 rcode = free_pipe(pi, indent);
1589 final_printf("%s pipe followup code %d\n", ind, pi->followup); 1567 final_printf("%s pipe followup code %d\n", ind, pi->followup);
1590 next=pi->next; 1568 next=pi->next;
1591 pi->next=NULL; 1569 pi->next=NULL;
@@ -1601,10 +1579,10 @@ static int run_list(struct pipe *pi)
1601 if (fake_mode==0) { 1579 if (fake_mode==0) {
1602 rcode = run_list_real(pi); 1580 rcode = run_list_real(pi);
1603 } 1581 }
1604 /* run_list_test has the side effect of clearing memory 1582 /* free_pipe_list has the side effect of clearing memory
1605 * In the long run that function can be merged with run_list_real, 1583 * In the long run that function can be merged with run_list_real,
1606 * but doing that now would hobble the debugging effort. */ 1584 * but doing that now would hobble the debugging effort. */
1607 run_list_test(pi,0); 1585 free_pipe_list(pi,0);
1608 return rcode; 1586 return rcode;
1609} 1587}
1610 1588
@@ -2142,7 +2120,7 @@ FILE *generate_stream_from_list(struct pipe *head)
2142 pf = fdopen(channel[0],"r"); 2120 pf = fdopen(channel[0],"r");
2143 debug_printf("pipe on FILE *%p\n",pf); 2121 debug_printf("pipe on FILE *%p\n",pf);
2144#else 2122#else
2145 run_list_test(head,0); 2123 free_pipe_list(head,0);
2146 pf=popen("echo surrogate response","r"); 2124 pf=popen("echo surrogate response","r");
2147 debug_printf("started fake pipe on FILE *%p\n",pf); 2125 debug_printf("started fake pipe on FILE *%p\n",pf);
2148#endif 2126#endif