aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2006-06-13 18:50:20 +0000
committerRob Landley <rob@landley.net>2006-06-13 18:50:20 +0000
commitf94637959902b54b2a1c44e3608fa77158856005 (patch)
treecfea1463aa26aa4189055cf4286b3788e37d4bb1
parent7c7b0d74372da5fbde67513aa9ce162a555d4765 (diff)
downloadbusybox-w32-f94637959902b54b2a1c44e3608fa77158856005.tar.gz
busybox-w32-f94637959902b54b2a1c44e3608fa77158856005.tar.bz2
busybox-w32-f94637959902b54b2a1c44e3608fa77158856005.zip
Make lash smaller. (Use llist_t for file closing, and different allocation
functions.)
-rw-r--r--shell/lash.c95
1 files changed, 24 insertions, 71 deletions
diff --git a/shell/lash.c b/shell/lash.c
index 733b80cf5..216db8a7e 100644
--- a/shell/lash.c
+++ b/shell/lash.c
@@ -109,11 +109,6 @@ struct built_in_command {
109 int (*function) (struct child_prog *); /* function ptr */ 109 int (*function) (struct child_prog *); /* function ptr */
110}; 110};
111 111
112struct close_me {
113 int fd;
114 struct close_me *next;
115};
116
117/* function prototypes for builtins */ 112/* function prototypes for builtins */
118static int builtin_cd(struct child_prog *cmd); 113static int builtin_cd(struct child_prog *cmd);
119static int builtin_exec(struct child_prog *cmd); 114static int builtin_exec(struct child_prog *cmd);
@@ -129,9 +124,6 @@ static int builtin_read(struct child_prog *cmd);
129 124
130 125
131/* function prototypes for shell stuff */ 126/* function prototypes for shell stuff */
132static void mark_open(int fd);
133static void mark_closed(int fd);
134static void close_all(void);
135static void checkjobs(struct jobset *job_list); 127static void checkjobs(struct jobset *job_list);
136static void remove_job(struct jobset *j_list, struct job *job); 128static void remove_job(struct jobset *j_list, struct job *job);
137static int get_command(FILE * source, char *command); 129static int get_command(FILE * source, char *command);
@@ -177,7 +169,7 @@ static char *local_pending_command = NULL;
177static struct jobset job_list = { NULL, NULL }; 169static struct jobset job_list = { NULL, NULL };
178static int argc; 170static int argc;
179static char **argv; 171static char **argv;
180static struct close_me *close_me_head; 172static llist_t *close_me_list;
181static int last_return_code; 173static int last_return_code;
182static int last_bg_pid; 174static int last_bg_pid;
183static unsigned int last_jobid; 175static unsigned int last_jobid;
@@ -251,7 +243,7 @@ static int builtin_exec(struct child_prog *child)
251 if (child->argv[1] == NULL) 243 if (child->argv[1] == NULL)
252 return EXIT_SUCCESS; /* Really? */ 244 return EXIT_SUCCESS; /* Really? */
253 child->argv++; 245 child->argv++;
254 close_all(); 246 while(close_me_list) close((int)llist_pop(&close_me_list));
255 pseudo_exec(child); 247 pseudo_exec(child);
256 /* never returns */ 248 /* never returns */
257} 249}
@@ -453,11 +445,11 @@ static int builtin_source(struct child_prog *child)
453 } 445 }
454 446
455 fd=fileno(input); 447 fd=fileno(input);
456 mark_open(fd); 448 llist_add_to(&close_me_list, (void *)fd);
457 /* Now run the file */ 449 /* Now run the file */
458 status = busy_loop(input); 450 status = busy_loop(input);
459 fclose(input); 451 fclose(input);
460 mark_closed(fd); 452 llist_pop(&close_me_list);
461 return (status); 453 return (status);
462} 454}
463 455
@@ -472,36 +464,6 @@ static int builtin_unset(struct child_prog *child)
472 return EXIT_SUCCESS; 464 return EXIT_SUCCESS;
473} 465}
474 466
475static void mark_open(int fd)
476{
477 struct close_me *new = xmalloc(sizeof(struct close_me));
478 new->fd = fd;
479 new->next = close_me_head;
480 close_me_head = new;
481}
482
483static void mark_closed(int fd)
484{
485 struct close_me *tmp;
486 if (close_me_head == NULL || close_me_head->fd != fd)
487 bb_error_msg_and_die("corrupt close_me");
488 tmp = close_me_head;
489 close_me_head = close_me_head->next;
490 free(tmp);
491}
492
493static void close_all()
494{
495 struct close_me *c, *tmp;
496 for (c=close_me_head; c; c=tmp) {
497 close(c->fd);
498 tmp=c->next;
499 free(c);
500 }
501 close_me_head = NULL;
502}
503
504
505#ifdef CONFIG_LASH_JOB_CONTROL 467#ifdef CONFIG_LASH_JOB_CONTROL
506/* free up all memory from a job */ 468/* free up all memory from a job */
507static void free_job(struct job *cmd) 469static void free_job(struct job *cmd)
@@ -769,33 +731,29 @@ static char* itoa(register int i)
769 731
770static char * strsep_space( char *string, int * ix) 732static char * strsep_space( char *string, int * ix)
771{ 733{
772 char *token, *begin; 734 char *token;
773
774 begin = string;
775 735
776 /* Short circuit the trivial case */ 736 /* Short circuit the trivial case */
777 if ( !string || ! string[*ix]) 737 if ( !string || ! string[*ix])
778 return NULL; 738 return NULL;
779 739
780 /* Find the end of the token. */ 740 /* Find the end of the token. */
781 while( string && string[*ix] && !isspace(string[*ix]) ) { 741 while( string[*ix] && !isspace(string[*ix]) ) {
782 (*ix)++; 742 (*ix)++;
783 } 743 }
784 744
785 /* Find the end of any whitespace trailing behind 745 /* Find the end of any whitespace trailing behind
786 * the token and let that be part of the token */ 746 * the token and let that be part of the token */
787 while( string && string[*ix] && isspace(string[*ix]) ) { 747 while( string[*ix] && isspace(string[*ix]) ) {
788 (*ix)++; 748 (*ix)++;
789 } 749 }
790 750
791 if (! string && *ix==0) { 751 if (!*ix) {
792 /* Nothing useful was found */ 752 /* Nothing useful was found */
793 return NULL; 753 return NULL;
794 } 754 }
795 755
796 token = xmalloc(*ix+1); 756 token = bb_xstrndup(string, *ix);
797 token[*ix] = '\0';
798 strncpy(token, string, *ix);
799 757
800 return token; 758 return token;
801} 759}
@@ -980,7 +938,6 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg)
980 int argv_alloced; 938 int argv_alloced;
981 int saw_quote = 0; 939 int saw_quote = 0;
982 char quote = '\0'; 940 char quote = '\0';
983 int count;
984 struct child_prog *prog; 941 struct child_prog *prog;
985#ifdef CONFIG_LASH_PIPE_N_REDIRECTS 942#ifdef CONFIG_LASH_PIPE_N_REDIRECTS
986 int i; 943 int i;
@@ -1008,7 +965,7 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg)
1008 Getting clean memory relieves us of the task of NULL 965 Getting clean memory relieves us of the task of NULL
1009 terminating things and makes the rest of this look a bit 966 terminating things and makes the rest of this look a bit
1010 cleaner (though it is, admittedly, a tad less efficient) */ 967 cleaner (though it is, admittedly, a tad less efficient) */
1011 job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char)); 968 job->cmdbuf = command = xzalloc(2*strlen(*command_ptr) + 1);
1012 job->text = NULL; 969 job->text = NULL;
1013 970
1014 prog = job->progs; 971 prog = job->progs;
@@ -1209,14 +1166,10 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg)
1209 prog->argv[argc_l] = NULL; 1166 prog->argv[argc_l] = NULL;
1210 1167
1211 if (!return_command) { 1168 if (!return_command) {
1212 job->text = xmalloc(strlen(*command_ptr) + 1); 1169 job->text = bb_xstrdup(*command_ptr);
1213 strcpy(job->text, *command_ptr);
1214 } else { 1170 } else {
1215 /* This leaves any trailing spaces, which is a bit sloppy */ 1171 /* This leaves any trailing spaces, which is a bit sloppy */
1216 count = return_command - *command_ptr; 1172 job->text = bb_xstrndup(*command_ptr, return_command - *command_ptr);
1217 job->text = xmalloc(count + 1);
1218 strncpy(job->text, *command_ptr, count);
1219 job->text[count] = '\0';
1220 } 1173 }
1221 1174
1222 *command_ptr = return_command; 1175 *command_ptr = return_command;
@@ -1320,9 +1273,8 @@ static void insert_job(struct job *newjob, int inbg)
1320 newjob->job_list->fg = thejob; 1273 newjob->job_list->fg = thejob;
1321 1274
1322 /* move the new process group into the foreground */ 1275 /* move the new process group into the foreground */
1323 /* suppress messages when run from /linuxrc mag@sysgo.de */ 1276 /* Ignore errors since child could have already exited */
1324 if (tcsetpgrp(shell_terminal, newjob->pgrp) && errno != ENOTTY) 1277 tcsetpgrp(shell_terminal, newjob->pgrp);
1325 bb_perror_msg("tcsetpgrp");
1326 } 1278 }
1327#endif 1279#endif
1328} 1280}
@@ -1385,7 +1337,8 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
1385 signal(SIGTTOU, SIG_DFL); 1337 signal(SIGTTOU, SIG_DFL);
1386 signal(SIGCHLD, SIG_DFL); 1338 signal(SIGCHLD, SIG_DFL);
1387 1339
1388 close_all(); 1340 // Close all open filehandles.
1341 while(close_me_list) close((int)llist_pop(&close_me_list));
1389 1342
1390 if (outpipe[1]!=-1) { 1343 if (outpipe[1]!=-1) {
1391 close(outpipe[0]); 1344 close(outpipe[0]);
@@ -1447,7 +1400,7 @@ static int busy_loop(FILE * input)
1447 newjob.job_list = &job_list; 1400 newjob.job_list = &job_list;
1448 newjob.job_context = DEFAULT_CONTEXT; 1401 newjob.job_context = DEFAULT_CONTEXT;
1449 1402
1450 command = (char *) xcalloc(BUFSIZ, sizeof(char)); 1403 command = xzalloc(BUFSIZ);
1451 1404
1452 while (1) { 1405 while (1) {
1453 if (!job_list.fg) { 1406 if (!job_list.fg) {
@@ -1464,7 +1417,7 @@ static int busy_loop(FILE * input)
1464 1417
1465 if (! expand_arguments(next_command)) { 1418 if (! expand_arguments(next_command)) {
1466 free(command); 1419 free(command);
1467 command = (char *) xcalloc(BUFSIZ, sizeof(char)); 1420 command = xzalloc(BUFSIZ);
1468 next_command = NULL; 1421 next_command = NULL;
1469 continue; 1422 continue;
1470 } 1423 }
@@ -1478,7 +1431,7 @@ static int busy_loop(FILE * input)
1478 } 1431 }
1479 else { 1432 else {
1480 free(command); 1433 free(command);
1481 command = (char *) xcalloc(BUFSIZ, sizeof(char)); 1434 command = (char *) xzalloc(BUFSIZ);
1482 next_command = NULL; 1435 next_command = NULL;
1483 } 1436 }
1484 } else { 1437 } else {
@@ -1607,7 +1560,7 @@ int lash_main(int argc_l, char **argv_l)
1607 /* These variables need re-initializing when recursing */ 1560 /* These variables need re-initializing when recursing */
1608 last_jobid = 0; 1561 last_jobid = 0;
1609 local_pending_command = NULL; 1562 local_pending_command = NULL;
1610 close_me_head = NULL; 1563 close_me_list = NULL;
1611 job_list.head = NULL; 1564 job_list.head = NULL;
1612 job_list.fg = NULL; 1565 job_list.fg = NULL;
1613 last_return_code=1; 1566 last_return_code=1;
@@ -1616,12 +1569,11 @@ int lash_main(int argc_l, char **argv_l)
1616 FILE *prof_input; 1569 FILE *prof_input;
1617 prof_input = fopen("/etc/profile", "r"); 1570 prof_input = fopen("/etc/profile", "r");
1618 if (prof_input) { 1571 if (prof_input) {
1619 int tmp_fd = fileno(prof_input); 1572 llist_add_to(&close_me_list, (void *)fileno(prof_input));
1620 mark_open(tmp_fd);
1621 /* Now run the file */ 1573 /* Now run the file */
1622 busy_loop(prof_input); 1574 busy_loop(prof_input);
1623 fclose(prof_input); 1575 fclose(prof_input);
1624 mark_closed(tmp_fd); 1576 llist_pop(&close_me_list);
1625 } 1577 }
1626 } 1578 }
1627 1579
@@ -1664,7 +1616,8 @@ int lash_main(int argc_l, char **argv_l)
1664 } else if (local_pending_command==NULL) { 1616 } else if (local_pending_command==NULL) {
1665 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]); 1617 //printf( "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
1666 input = bb_xfopen(argv[optind], "r"); 1618 input = bb_xfopen(argv[optind], "r");
1667 mark_open(fileno(input)); /* be lazy, never mark this closed */ 1619 /* be lazy, never mark this closed */
1620 llist_add_to(&close_me_list, (void *)fileno(input));
1668 } 1621 }
1669 1622
1670 /* initialize the cwd -- this is never freed...*/ 1623 /* initialize the cwd -- this is never freed...*/