Patch from larry doolittle to be ever so careful to cleanup

all open file descriptors, lest wierdness happen later.
This commit is contained in:
Eric Andersen 2001-01-05 20:58:22 +00:00
parent 0bcc813a34
commit 8ea28be6d2
3 changed files with 216 additions and 48 deletions

88
lash.c
View File

@ -25,6 +25,12 @@
* *
*/ */
/* The parsing engine of this program is officially at a dead-end.
* Future work in that direction should move to the work posted
* at http://doolittle.faludi.com/~larry/parser.html .
* A start on the integration of that work with the rest of sh.c
* is at http://codepoet.org/sh.c .
*/
// //
//This works pretty well now, and is now on by default. //This works pretty well now, and is now on by default.
#define BB_FEATURE_SH_ENVIRONMENT #define BB_FEATURE_SH_ENVIRONMENT
@ -117,6 +123,11 @@ struct built_in_command {
int (*function) (struct child_prog *); /* function ptr */ int (*function) (struct child_prog *); /* function ptr */
}; };
struct close_me {
int fd;
struct close_me *next;
};
/* function prototypes for builtins */ /* function prototypes for builtins */
static int builtin_cd(struct child_prog *cmd); static int builtin_cd(struct child_prog *cmd);
static int builtin_env(struct child_prog *dummy); static int builtin_env(struct child_prog *dummy);
@ -141,6 +152,8 @@ static int run_command_predicate(char *cmd);
/* function prototypes for shell stuff */ /* function prototypes for shell stuff */
static void mark_open(int fd);
static void mark_closed(int fd);
static void checkjobs(struct jobset *job_list); static void checkjobs(struct jobset *job_list);
static int get_command(FILE * source, char *command); static int get_command(FILE * source, char *command);
static int parse_command(char **command_ptr, struct job *job, int *inbg); static int parse_command(char **command_ptr, struct job *job, int *inbg);
@ -194,6 +207,7 @@ static char *local_pending_command;
static struct jobset job_list = { NULL, NULL }; static struct jobset job_list = { NULL, NULL };
static int argc; static int argc;
static char **argv; static char **argv;
static struct close_me *close_me_head = NULL;
#ifdef BB_FEATURE_SH_ENVIRONMENT #ifdef BB_FEATURE_SH_ENVIRONMENT
static int last_bg_pid=-1; static int last_bg_pid=-1;
static int last_return_code=-1; static int last_return_code=-1;
@ -545,6 +559,7 @@ static int builtin_source(struct child_prog *child)
{ {
FILE *input; FILE *input;
int status; int status;
int fd;
if (child->argv[1] == NULL) if (child->argv[1] == NULL)
return EXIT_FAILURE; return EXIT_FAILURE;
@ -555,9 +570,12 @@ static int builtin_source(struct child_prog *child)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
fd=fileno(input);
mark_open(fd);
/* Now run the file */ /* Now run the file */
status = busy_loop(input); status = busy_loop(input);
fclose(input); fclose(input);
mark_closed(fd);
return (status); return (status);
} }
@ -592,6 +610,34 @@ static int run_command_predicate(char *cmd)
} }
#endif #endif
static void mark_open(int fd)
{
struct close_me *new = xmalloc(sizeof(struct close_me));
new->fd = fd;
new->next = close_me_head;
close_me_head = new;
}
static void mark_closed(int fd)
{
struct close_me *tmp;
if (close_me_head == NULL || close_me_head->fd != fd)
error_msg_and_die("corrupt close_me");
tmp = close_me_head;
close_me_head = close_me_head->next;
free(tmp);
}
static void close_all()
{
struct close_me *c;
for (c=close_me_head; c; c=c->next) {
close(c->fd);
}
close_me_head = NULL;
}
/* free up all memory from a job */ /* free up all memory from a job */
static void free_job(struct job *cmd) static void free_job(struct job *cmd)
{ {
@ -767,7 +813,7 @@ static char* setup_prompt_string(int state)
static int get_command(FILE * source, char *command) static int get_command(FILE * source, char *command)
{ {
char *prompt_str; char *prompt_str;
if (source == NULL) { if (source == NULL) {
if (local_pending_command) { if (local_pending_command) {
/* a command specified (-c option): return it & mark it done */ /* a command specified (-c option): return it & mark it done */
@ -781,7 +827,7 @@ static int get_command(FILE * source, char *command)
if (source == stdin) { if (source == stdin) {
prompt_str = setup_prompt_string(shell_context); prompt_str = setup_prompt_string(shell_context);
#ifdef BB_FEATURE_SH_COMMAND_EDITING #ifdef BB_FEATURE_SH_COMMAND_EDITING
/* /*
** enable command line editing only while a command line ** enable command line editing only while a command line
@ -791,11 +837,12 @@ static int get_command(FILE * source, char *command)
*/ */
cmdedit_init(); cmdedit_init();
cmdedit_read_input(prompt_str, command); cmdedit_read_input(prompt_str, command);
free( prompt_str); free(prompt_str);
cmdedit_terminate(); cmdedit_terminate();
return 0; return 0;
#else #else
fprintf(stdout, "%s", prompt_str); fputs(prompt_str, stdout);
free(prompt_str);
#endif #endif
} }
@ -1151,6 +1198,9 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg)
#ifdef BB_FEATURE_SH_BACKTICKS #ifdef BB_FEATURE_SH_BACKTICKS
case '`': case '`':
/* Exec a backtick-ed command */ /* Exec a backtick-ed command */
/* Besides any previous brokenness, I have not
* updated backtick handling for close_me support.
* I don't know if it needs it or not. -- LRD */
{ {
char* charptr1=NULL, *charptr2; char* charptr1=NULL, *charptr2;
char* ptr=NULL; char* ptr=NULL;
@ -1359,8 +1409,7 @@ static int pseudo_exec(struct child_prog *child)
#endif #endif
execvp(child->argv[0], child->argv); execvp(child->argv[0], child->argv);
error_msg_and_die("%s: %s\n", child->argv[0], perror_msg_and_die("%s", child->argv[0]);
strerror(errno));
} }
static void insert_job(struct job *newjob, int inbg) static void insert_job(struct job *newjob, int inbg)
@ -1464,6 +1513,8 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
if (!(child->pid = fork())) { if (!(child->pid = fork())) {
signal(SIGTTOU, SIG_DFL); signal(SIGTTOU, SIG_DFL);
close_all();
if (outpipe[1]!=-1) { if (outpipe[1]!=-1) {
close(outpipe[0]); close(outpipe[0]);
} }
@ -1559,7 +1610,8 @@ static int busy_loop(FILE * input)
while (!job_list.fg->progs[i].pid || while (!job_list.fg->progs[i].pid ||
job_list.fg->progs[i].is_stopped == 1) i++; job_list.fg->progs[i].is_stopped == 1) i++;
waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED); if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
if (WIFEXITED(status) || WIFSIGNALED(status)) { if (WIFEXITED(status) || WIFSIGNALED(status)) {
/* the child exited */ /* the child exited */
@ -1649,15 +1701,18 @@ int shell_main(int argc_l, char **argv_l)
#endif #endif
if (argv[0] && argv[0][0] == '-') { if (argv[0] && argv[0][0] == '-') {
FILE *input; FILE *prof_input;
input = fopen("/etc/profile", "r"); prof_input = fopen("/etc/profile", "r");
if (!input) { if (!prof_input) {
fprintf(stdout, "Couldn't open file '/etc/profile'\n"); fprintf(stdout, "Couldn't open file '/etc/profile'\n");
} else { } else {
/* Now run the file */ int tmp_fd = fileno(prof_input);
busy_loop(input); mark_open(tmp_fd);
fclose(input); /* Now run the file */
} busy_loop(prof_input);
fclose(prof_input);
mark_closed(tmp_fd);
}
} }
while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) { while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
@ -1701,6 +1756,7 @@ int shell_main(int argc_l, char **argv_l)
} else if (local_pending_command==NULL) { } else if (local_pending_command==NULL) {
//fprintf(stdout, "optind=%d argv[optind]='%s'\n", optind, argv[optind]); //fprintf(stdout, "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
input = xfopen(argv[optind], "r"); input = xfopen(argv[optind], "r");
mark_open(fileno(input)); /* be lazy, never mark this closed */
} }
/* initialize the cwd -- this is never freed...*/ /* initialize the cwd -- this is never freed...*/

88
sh.c
View File

@ -25,6 +25,12 @@
* *
*/ */
/* The parsing engine of this program is officially at a dead-end.
* Future work in that direction should move to the work posted
* at http://doolittle.faludi.com/~larry/parser.html .
* A start on the integration of that work with the rest of sh.c
* is at http://codepoet.org/sh.c .
*/
// //
//This works pretty well now, and is now on by default. //This works pretty well now, and is now on by default.
#define BB_FEATURE_SH_ENVIRONMENT #define BB_FEATURE_SH_ENVIRONMENT
@ -117,6 +123,11 @@ struct built_in_command {
int (*function) (struct child_prog *); /* function ptr */ int (*function) (struct child_prog *); /* function ptr */
}; };
struct close_me {
int fd;
struct close_me *next;
};
/* function prototypes for builtins */ /* function prototypes for builtins */
static int builtin_cd(struct child_prog *cmd); static int builtin_cd(struct child_prog *cmd);
static int builtin_env(struct child_prog *dummy); static int builtin_env(struct child_prog *dummy);
@ -141,6 +152,8 @@ static int run_command_predicate(char *cmd);
/* function prototypes for shell stuff */ /* function prototypes for shell stuff */
static void mark_open(int fd);
static void mark_closed(int fd);
static void checkjobs(struct jobset *job_list); static void checkjobs(struct jobset *job_list);
static int get_command(FILE * source, char *command); static int get_command(FILE * source, char *command);
static int parse_command(char **command_ptr, struct job *job, int *inbg); static int parse_command(char **command_ptr, struct job *job, int *inbg);
@ -194,6 +207,7 @@ static char *local_pending_command;
static struct jobset job_list = { NULL, NULL }; static struct jobset job_list = { NULL, NULL };
static int argc; static int argc;
static char **argv; static char **argv;
static struct close_me *close_me_head = NULL;
#ifdef BB_FEATURE_SH_ENVIRONMENT #ifdef BB_FEATURE_SH_ENVIRONMENT
static int last_bg_pid=-1; static int last_bg_pid=-1;
static int last_return_code=-1; static int last_return_code=-1;
@ -545,6 +559,7 @@ static int builtin_source(struct child_prog *child)
{ {
FILE *input; FILE *input;
int status; int status;
int fd;
if (child->argv[1] == NULL) if (child->argv[1] == NULL)
return EXIT_FAILURE; return EXIT_FAILURE;
@ -555,9 +570,12 @@ static int builtin_source(struct child_prog *child)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
fd=fileno(input);
mark_open(fd);
/* Now run the file */ /* Now run the file */
status = busy_loop(input); status = busy_loop(input);
fclose(input); fclose(input);
mark_closed(fd);
return (status); return (status);
} }
@ -592,6 +610,34 @@ static int run_command_predicate(char *cmd)
} }
#endif #endif
static void mark_open(int fd)
{
struct close_me *new = xmalloc(sizeof(struct close_me));
new->fd = fd;
new->next = close_me_head;
close_me_head = new;
}
static void mark_closed(int fd)
{
struct close_me *tmp;
if (close_me_head == NULL || close_me_head->fd != fd)
error_msg_and_die("corrupt close_me");
tmp = close_me_head;
close_me_head = close_me_head->next;
free(tmp);
}
static void close_all()
{
struct close_me *c;
for (c=close_me_head; c; c=c->next) {
close(c->fd);
}
close_me_head = NULL;
}
/* free up all memory from a job */ /* free up all memory from a job */
static void free_job(struct job *cmd) static void free_job(struct job *cmd)
{ {
@ -767,7 +813,7 @@ static char* setup_prompt_string(int state)
static int get_command(FILE * source, char *command) static int get_command(FILE * source, char *command)
{ {
char *prompt_str; char *prompt_str;
if (source == NULL) { if (source == NULL) {
if (local_pending_command) { if (local_pending_command) {
/* a command specified (-c option): return it & mark it done */ /* a command specified (-c option): return it & mark it done */
@ -781,7 +827,7 @@ static int get_command(FILE * source, char *command)
if (source == stdin) { if (source == stdin) {
prompt_str = setup_prompt_string(shell_context); prompt_str = setup_prompt_string(shell_context);
#ifdef BB_FEATURE_SH_COMMAND_EDITING #ifdef BB_FEATURE_SH_COMMAND_EDITING
/* /*
** enable command line editing only while a command line ** enable command line editing only while a command line
@ -791,11 +837,12 @@ static int get_command(FILE * source, char *command)
*/ */
cmdedit_init(); cmdedit_init();
cmdedit_read_input(prompt_str, command); cmdedit_read_input(prompt_str, command);
free( prompt_str); free(prompt_str);
cmdedit_terminate(); cmdedit_terminate();
return 0; return 0;
#else #else
fprintf(stdout, "%s", prompt_str); fputs(prompt_str, stdout);
free(prompt_str);
#endif #endif
} }
@ -1151,6 +1198,9 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg)
#ifdef BB_FEATURE_SH_BACKTICKS #ifdef BB_FEATURE_SH_BACKTICKS
case '`': case '`':
/* Exec a backtick-ed command */ /* Exec a backtick-ed command */
/* Besides any previous brokenness, I have not
* updated backtick handling for close_me support.
* I don't know if it needs it or not. -- LRD */
{ {
char* charptr1=NULL, *charptr2; char* charptr1=NULL, *charptr2;
char* ptr=NULL; char* ptr=NULL;
@ -1359,8 +1409,7 @@ static int pseudo_exec(struct child_prog *child)
#endif #endif
execvp(child->argv[0], child->argv); execvp(child->argv[0], child->argv);
error_msg_and_die("%s: %s\n", child->argv[0], perror_msg_and_die("%s", child->argv[0]);
strerror(errno));
} }
static void insert_job(struct job *newjob, int inbg) static void insert_job(struct job *newjob, int inbg)
@ -1464,6 +1513,8 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
if (!(child->pid = fork())) { if (!(child->pid = fork())) {
signal(SIGTTOU, SIG_DFL); signal(SIGTTOU, SIG_DFL);
close_all();
if (outpipe[1]!=-1) { if (outpipe[1]!=-1) {
close(outpipe[0]); close(outpipe[0]);
} }
@ -1559,7 +1610,8 @@ static int busy_loop(FILE * input)
while (!job_list.fg->progs[i].pid || while (!job_list.fg->progs[i].pid ||
job_list.fg->progs[i].is_stopped == 1) i++; job_list.fg->progs[i].is_stopped == 1) i++;
waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED); if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
if (WIFEXITED(status) || WIFSIGNALED(status)) { if (WIFEXITED(status) || WIFSIGNALED(status)) {
/* the child exited */ /* the child exited */
@ -1649,15 +1701,18 @@ int shell_main(int argc_l, char **argv_l)
#endif #endif
if (argv[0] && argv[0][0] == '-') { if (argv[0] && argv[0][0] == '-') {
FILE *input; FILE *prof_input;
input = fopen("/etc/profile", "r"); prof_input = fopen("/etc/profile", "r");
if (!input) { if (!prof_input) {
fprintf(stdout, "Couldn't open file '/etc/profile'\n"); fprintf(stdout, "Couldn't open file '/etc/profile'\n");
} else { } else {
/* Now run the file */ int tmp_fd = fileno(prof_input);
busy_loop(input); mark_open(tmp_fd);
fclose(input); /* Now run the file */
} busy_loop(prof_input);
fclose(prof_input);
mark_closed(tmp_fd);
}
} }
while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) { while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
@ -1701,6 +1756,7 @@ int shell_main(int argc_l, char **argv_l)
} else if (local_pending_command==NULL) { } else if (local_pending_command==NULL) {
//fprintf(stdout, "optind=%d argv[optind]='%s'\n", optind, argv[optind]); //fprintf(stdout, "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
input = xfopen(argv[optind], "r"); input = xfopen(argv[optind], "r");
mark_open(fileno(input)); /* be lazy, never mark this closed */
} }
/* initialize the cwd -- this is never freed...*/ /* initialize the cwd -- this is never freed...*/

View File

@ -25,6 +25,12 @@
* *
*/ */
/* The parsing engine of this program is officially at a dead-end.
* Future work in that direction should move to the work posted
* at http://doolittle.faludi.com/~larry/parser.html .
* A start on the integration of that work with the rest of sh.c
* is at http://codepoet.org/sh.c .
*/
// //
//This works pretty well now, and is now on by default. //This works pretty well now, and is now on by default.
#define BB_FEATURE_SH_ENVIRONMENT #define BB_FEATURE_SH_ENVIRONMENT
@ -117,6 +123,11 @@ struct built_in_command {
int (*function) (struct child_prog *); /* function ptr */ int (*function) (struct child_prog *); /* function ptr */
}; };
struct close_me {
int fd;
struct close_me *next;
};
/* function prototypes for builtins */ /* function prototypes for builtins */
static int builtin_cd(struct child_prog *cmd); static int builtin_cd(struct child_prog *cmd);
static int builtin_env(struct child_prog *dummy); static int builtin_env(struct child_prog *dummy);
@ -141,6 +152,8 @@ static int run_command_predicate(char *cmd);
/* function prototypes for shell stuff */ /* function prototypes for shell stuff */
static void mark_open(int fd);
static void mark_closed(int fd);
static void checkjobs(struct jobset *job_list); static void checkjobs(struct jobset *job_list);
static int get_command(FILE * source, char *command); static int get_command(FILE * source, char *command);
static int parse_command(char **command_ptr, struct job *job, int *inbg); static int parse_command(char **command_ptr, struct job *job, int *inbg);
@ -194,6 +207,7 @@ static char *local_pending_command;
static struct jobset job_list = { NULL, NULL }; static struct jobset job_list = { NULL, NULL };
static int argc; static int argc;
static char **argv; static char **argv;
static struct close_me *close_me_head = NULL;
#ifdef BB_FEATURE_SH_ENVIRONMENT #ifdef BB_FEATURE_SH_ENVIRONMENT
static int last_bg_pid=-1; static int last_bg_pid=-1;
static int last_return_code=-1; static int last_return_code=-1;
@ -545,6 +559,7 @@ static int builtin_source(struct child_prog *child)
{ {
FILE *input; FILE *input;
int status; int status;
int fd;
if (child->argv[1] == NULL) if (child->argv[1] == NULL)
return EXIT_FAILURE; return EXIT_FAILURE;
@ -555,9 +570,12 @@ static int builtin_source(struct child_prog *child)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
fd=fileno(input);
mark_open(fd);
/* Now run the file */ /* Now run the file */
status = busy_loop(input); status = busy_loop(input);
fclose(input); fclose(input);
mark_closed(fd);
return (status); return (status);
} }
@ -592,6 +610,34 @@ static int run_command_predicate(char *cmd)
} }
#endif #endif
static void mark_open(int fd)
{
struct close_me *new = xmalloc(sizeof(struct close_me));
new->fd = fd;
new->next = close_me_head;
close_me_head = new;
}
static void mark_closed(int fd)
{
struct close_me *tmp;
if (close_me_head == NULL || close_me_head->fd != fd)
error_msg_and_die("corrupt close_me");
tmp = close_me_head;
close_me_head = close_me_head->next;
free(tmp);
}
static void close_all()
{
struct close_me *c;
for (c=close_me_head; c; c=c->next) {
close(c->fd);
}
close_me_head = NULL;
}
/* free up all memory from a job */ /* free up all memory from a job */
static void free_job(struct job *cmd) static void free_job(struct job *cmd)
{ {
@ -767,7 +813,7 @@ static char* setup_prompt_string(int state)
static int get_command(FILE * source, char *command) static int get_command(FILE * source, char *command)
{ {
char *prompt_str; char *prompt_str;
if (source == NULL) { if (source == NULL) {
if (local_pending_command) { if (local_pending_command) {
/* a command specified (-c option): return it & mark it done */ /* a command specified (-c option): return it & mark it done */
@ -781,7 +827,7 @@ static int get_command(FILE * source, char *command)
if (source == stdin) { if (source == stdin) {
prompt_str = setup_prompt_string(shell_context); prompt_str = setup_prompt_string(shell_context);
#ifdef BB_FEATURE_SH_COMMAND_EDITING #ifdef BB_FEATURE_SH_COMMAND_EDITING
/* /*
** enable command line editing only while a command line ** enable command line editing only while a command line
@ -791,11 +837,12 @@ static int get_command(FILE * source, char *command)
*/ */
cmdedit_init(); cmdedit_init();
cmdedit_read_input(prompt_str, command); cmdedit_read_input(prompt_str, command);
free( prompt_str); free(prompt_str);
cmdedit_terminate(); cmdedit_terminate();
return 0; return 0;
#else #else
fprintf(stdout, "%s", prompt_str); fputs(prompt_str, stdout);
free(prompt_str);
#endif #endif
} }
@ -1151,6 +1198,9 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg)
#ifdef BB_FEATURE_SH_BACKTICKS #ifdef BB_FEATURE_SH_BACKTICKS
case '`': case '`':
/* Exec a backtick-ed command */ /* Exec a backtick-ed command */
/* Besides any previous brokenness, I have not
* updated backtick handling for close_me support.
* I don't know if it needs it or not. -- LRD */
{ {
char* charptr1=NULL, *charptr2; char* charptr1=NULL, *charptr2;
char* ptr=NULL; char* ptr=NULL;
@ -1359,8 +1409,7 @@ static int pseudo_exec(struct child_prog *child)
#endif #endif
execvp(child->argv[0], child->argv); execvp(child->argv[0], child->argv);
error_msg_and_die("%s: %s\n", child->argv[0], perror_msg_and_die("%s", child->argv[0]);
strerror(errno));
} }
static void insert_job(struct job *newjob, int inbg) static void insert_job(struct job *newjob, int inbg)
@ -1464,6 +1513,8 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
if (!(child->pid = fork())) { if (!(child->pid = fork())) {
signal(SIGTTOU, SIG_DFL); signal(SIGTTOU, SIG_DFL);
close_all();
if (outpipe[1]!=-1) { if (outpipe[1]!=-1) {
close(outpipe[0]); close(outpipe[0]);
} }
@ -1559,7 +1610,8 @@ static int busy_loop(FILE * input)
while (!job_list.fg->progs[i].pid || while (!job_list.fg->progs[i].pid ||
job_list.fg->progs[i].is_stopped == 1) i++; job_list.fg->progs[i].is_stopped == 1) i++;
waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED); if (waitpid(job_list.fg->progs[i].pid, &status, WUNTRACED)<0)
perror_msg_and_die("waitpid(%d)",job_list.fg->progs[i].pid);
if (WIFEXITED(status) || WIFSIGNALED(status)) { if (WIFEXITED(status) || WIFSIGNALED(status)) {
/* the child exited */ /* the child exited */
@ -1649,15 +1701,18 @@ int shell_main(int argc_l, char **argv_l)
#endif #endif
if (argv[0] && argv[0][0] == '-') { if (argv[0] && argv[0][0] == '-') {
FILE *input; FILE *prof_input;
input = fopen("/etc/profile", "r"); prof_input = fopen("/etc/profile", "r");
if (!input) { if (!prof_input) {
fprintf(stdout, "Couldn't open file '/etc/profile'\n"); fprintf(stdout, "Couldn't open file '/etc/profile'\n");
} else { } else {
/* Now run the file */ int tmp_fd = fileno(prof_input);
busy_loop(input); mark_open(tmp_fd);
fclose(input); /* Now run the file */
} busy_loop(prof_input);
fclose(prof_input);
mark_closed(tmp_fd);
}
} }
while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) { while ((opt = getopt(argc_l, argv_l, "cxi")) > 0) {
@ -1701,6 +1756,7 @@ int shell_main(int argc_l, char **argv_l)
} else if (local_pending_command==NULL) { } else if (local_pending_command==NULL) {
//fprintf(stdout, "optind=%d argv[optind]='%s'\n", optind, argv[optind]); //fprintf(stdout, "optind=%d argv[optind]='%s'\n", optind, argv[optind]);
input = xfopen(argv[optind], "r"); input = xfopen(argv[optind], "r");
mark_open(fileno(input)); /* be lazy, never mark this closed */
} }
/* initialize the cwd -- this is never freed...*/ /* initialize the cwd -- this is never freed...*/