diff options
author | Eric Andersen <andersen@codepoet.org> | 2004-02-10 04:07:45 +0300 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2004-02-10 04:07:45 +0300 |
commit | ff9ad47d794fb26022a0e0b14d4ed946bd3bada6 (patch) | |
tree | aec942cfc8b4b5d1bab9535e048e3dbee542e7d2 /shell/lash.c | |
parent | a0e4c3f119a216c890366e01163080e6e45fea7d (diff) |
Support disabling pipe and redirect support
Diffstat (limited to 'shell/lash.c')
-rw-r--r-- | shell/lash.c | 107 |
1 files changed, 67 insertions, 40 deletions
diff --git a/shell/lash.c b/shell/lash.c index 1fcd63bdf..3675d21df 100644 --- a/shell/lash.c +++ b/shell/lash.c @@ -56,14 +56,18 @@ #include <glob.h> #define expand_t glob_t +/* Always enable for the moment... */ +#define CONFIG_LASH_PIPE_N_REDIRECTS static const int MAX_READ = 128; /* size of input buffer for `read' builtin */ #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" +#ifdef CONFIG_LASH_PIPE_N_REDIRECTS enum redir_type { REDIRECT_INPUT, REDIRECT_OVERWRITE, REDIRECT_APPEND }; +#endif static const unsigned int DEFAULT_CONTEXT=0x1; static const unsigned int IF_TRUE_CONTEXT=0x2; @@ -71,25 +75,28 @@ static const unsigned int IF_FALSE_CONTEXT=0x4; static const unsigned int THEN_EXP_CONTEXT=0x8; static const unsigned int ELSE_EXP_CONTEXT=0x10; - -struct jobset { - struct job *head; /* head of list of running jobs */ - struct job *fg; /* current foreground job */ -}; - +#ifdef CONFIG_LASH_PIPE_N_REDIRECTS struct redir_struct { enum redir_type type; /* type of redirection */ int fd; /* file descriptor being redirected */ char *filename; /* file to redirect fd to */ }; +#endif struct child_prog { pid_t pid; /* 0 if exited */ char **argv; /* program name and arguments */ int num_redirects; /* elements in redirection array */ - struct redir_struct *redirects; /* I/O redirects */ int is_stopped; /* is the program currently running? */ struct job *family; /* pointer back to the child's parent job */ +#ifdef CONFIG_LASH_PIPE_N_REDIRECTS + struct redir_struct *redirects; /* I/O redirects */ +#endif +}; + +struct jobset { + struct job *head; /* head of list of running jobs */ + struct job *fg; /* current foreground job */ }; struct job { @@ -514,8 +521,10 @@ static void free_job(struct job *cmd) for (i = 0; i < cmd->num_progs; i++) { free(cmd->progs[i].argv); +#ifdef CONFIG_LASH_PIPE_N_REDIRECTS if (cmd->progs[i].redirects) free(cmd->progs[i].redirects); +#endif } free(cmd->progs); free(cmd->text); @@ -548,7 +557,7 @@ static void remove_job(struct jobset *j_list, struct job *job) free(job); } -/* Checks to see if any background processes have exited -- if they +/* 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(struct jobset *j_list) { @@ -593,7 +602,7 @@ static void checkjobs(struct jobset *j_list) printf(JOB_STATUS_FORMAT, job->jobid, "Stopped", job->text); } -#endif +#endif } } @@ -601,6 +610,7 @@ static void checkjobs(struct jobset *j_list) bb_perror_msg("waitpid"); } +#ifdef CONFIG_LASH_PIPE_N_REDIRECTS /* squirrel != NULL means we squirrel away copies of stdin, stdout, * and stderr if they are redirected. */ static int setup_redirects(struct child_prog *prog, int squirrel[]) @@ -656,6 +666,15 @@ static void restore_redirects(int squirrel[]) } } } +#else +static inline int setup_redirects(struct child_prog *prog, int squirrel[]) +{ + return 0; +} +static inline void restore_redirects(int squirrel[]) +{ +} +#endif static inline void cmdedit_set_initial_prompt(void) { @@ -665,7 +684,7 @@ static inline void cmdedit_set_initial_prompt(void) PS1 = getenv("PS1"); if(PS1==0) PS1 = "\\w \\$ "; -#endif +#endif } static inline void setup_prompt_string(char **prompt_str) @@ -682,7 +701,7 @@ static inline void setup_prompt_string(char **prompt_str) } #else *prompt_str = (shell_context==0)? PS1 : PS2; -#endif +#endif } static int get_command(FILE * source, char *command) @@ -761,7 +780,7 @@ char * strsep_space( char *string, int * ix) (*ix)++; } - /* Find the end of any whitespace trailing behind + /* Find the end of any whitespace trailing behind * the token and let that be part of the token */ while( string && string[*ix] && isspace(string[*ix]) ) { (*ix)++; @@ -774,7 +793,7 @@ char * strsep_space( char *string, int * ix) token = xmalloc(*ix+1); token[*ix] = '\0'; - strncpy(token, string, *ix); + strncpy(token, string, *ix); return token; } @@ -789,10 +808,10 @@ static int expand_arguments(char *command) int flags = GLOB_NOCHECK #ifdef GLOB_BRACE | GLOB_BRACE -#endif +#endif #ifdef GLOB_TILDE | GLOB_TILDE -#endif +#endif ; /* get rid of the terminating \n */ @@ -817,7 +836,7 @@ static int expand_arguments(char *command) * we write stuff into the original (in a minute) */ cmd = cmd_copy = bb_xstrdup(command); *command = '\0'; - for (ix = 0, tmpcmd = cmd; + for (ix = 0, tmpcmd = cmd; (tmpcmd = strsep_space(cmd, &ix)) != NULL; cmd += ix, ix=0) { if (*tmpcmd == '\0') break; @@ -832,7 +851,7 @@ static int expand_arguments(char *command) return FALSE; } else if (retval != 0) { /* Some other error. GLOB_NOMATCH shouldn't - * happen because of the GLOB_NOCHECK flag in + * happen because of the GLOB_NOCHECK flag in * the glob call. */ bb_error_msg("syntax error"); return FALSE; @@ -856,7 +875,7 @@ static int expand_arguments(char *command) free(cmd_copy); trim(command); - /* Now do the shell variable substitutions which + /* Now do the shell variable substitutions which * wordexp can't do for us, namely $? and $! */ src = command; while((dst = strchr(src,'$')) != NULL){ @@ -946,21 +965,25 @@ static int expand_arguments(char *command) /* Return cmd->num_progs as 0 if no command is present (e.g. an empty line). If a valid command is found, command_ptr is set to point to - the beginning of the next command (if the original command had more - then one job associated with it) or NULL if no more commands are + the beginning of the next command (if the original command had more + then one job associated with it) or NULL if no more commands are present. */ static int parse_command(char **command_ptr, struct job *job, int *inbg) { char *command; char *return_command = NULL; - char *src, *buf, *chptr; + char *src, *buf; int argc_l = 0; int done = 0; int argv_alloced; - int i, saw_quote = 0; + int saw_quote = 0; char quote = '\0'; int count; struct child_prog *prog; +#ifdef CONFIG_LASH_PIPE_N_REDIRECTS + int i; + char *chptr; +#endif /* skip leading white space */ while (**command_ptr && isspace(**command_ptr)) @@ -976,21 +999,23 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg) job->num_progs = 1; job->progs = xmalloc(sizeof(*job->progs)); - /* We set the argv elements to point inside of this string. The + /* We set the argv elements to point inside of this string. The memory is freed by free_job(). Allocate twice the original length in case we need to quote every single character. - Getting clean memory relieves us of the task of NULL - terminating things and makes the rest of this look a bit + Getting clean memory relieves us of the task of NULL + terminating things and makes the rest of this look a bit cleaner (though it is, admittedly, a tad less efficient) */ job->cmdbuf = command = xcalloc(2*strlen(*command_ptr) + 1, sizeof(char)); job->text = NULL; prog = job->progs; prog->num_redirects = 0; - prog->redirects = NULL; prog->is_stopped = 0; prog->family = job; +#ifdef CONFIG_LASH_PIPE_N_REDIRECTS + prog->redirects = NULL; +#endif argv_alloced = 5; prog->argv = xmalloc(sizeof(*prog->argv) * argv_alloced); @@ -1046,6 +1071,7 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg) done = 1; break; +#ifdef CONFIG_LASH_PIPE_N_REDIRECTS case '>': /* redirects */ case '<': i = prog->num_redirects++; @@ -1143,6 +1169,7 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg) src--; /* we'll ++ it at the end of the loop */ break; +#endif case '&': /* background */ *inbg = 1; @@ -1189,7 +1216,7 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg) } *command_ptr = return_command; - + return 0; } @@ -1236,7 +1263,7 @@ static int pseudo_exec(struct child_prog *child) #ifdef CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN /* If you enable CONFIG_FEATURE_SH_APPLETS_ALWAYS_WIN, then - * if you run /bin/cat, it will use BusyBox cat even if + * if you run /bin/cat, it will use BusyBox cat even if * /bin/cat exists on the filesystem and is _not_ busybox. * Some systems want this, others do not. Choose wisely. :-) */ @@ -1254,7 +1281,7 @@ static int pseudo_exec(struct child_prog *child) execvp(child->argv[0], child->argv); - /* Do not use bb_perror_msg_and_die() here, since we must not + /* Do not use bb_perror_msg_and_die() here, since we must not * call exit() but should call _exit() instead */ fprintf(stderr, "%s: %m\n", child->argv[0]); _exit(EXIT_FAILURE); @@ -1286,7 +1313,7 @@ static void insert_job(struct job *newjob, int inbg) thejob->stopped_progs = 0; if (inbg) { - /* we don't wait for background thejobs to return -- append it + /* we don't wait for background thejobs to return -- append it to the list of backgrounded thejobs and leave it alone */ printf("[%d] %d\n", thejob->jobid, newjob->progs[newjob->num_progs - 1].pid); @@ -1336,8 +1363,8 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2]) if (newjob->num_progs == 1) { for (x = bltins; x->cmd; x++) { if (strcmp(child->argv[0], x->cmd) == 0 ) { - int squirrel[] = {-1, -1, -1}; int rcode; + int squirrel[] = {-1, -1, -1}; setup_redirects(child, squirrel); rcode = x->function(child); restore_redirects(squirrel); @@ -1347,9 +1374,9 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2]) } #if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__) - if (!(child->pid = fork())) + if (!(child->pid = fork())) #else - if (!(child->pid = vfork())) + if (!(child->pid = vfork())) #endif { /* Set the handling for job control signals back to the default. */ @@ -1394,7 +1421,7 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2]) if (nextout != 1) close(nextout); - /* If there isn't another process, nextin is garbage + /* If there isn't another process, nextin is garbage but it doesn't matter */ nextin = pipefds[0]; } @@ -1446,7 +1473,7 @@ static int busy_loop(FILE * input) if (!parse_command(&next_command, &newjob, &inbg) && newjob.num_progs) { int pipefds[2] = {-1,-1}; - debug_printf( "job=%p fed to run_command by busy_loop()'\n", + debug_printf( "job=%p fed to run_command by busy_loop()'\n", &newjob); run_command(&newjob, inbg, pipefds); } @@ -1495,7 +1522,7 @@ static int busy_loop(FILE * input) /* move the shell to the foreground */ /* suppress messages when run from /linuxrc mag@sysgo.de */ if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY) - bb_perror_msg("tcsetpgrp"); + bb_perror_msg("tcsetpgrp"); } } } @@ -1508,7 +1535,7 @@ static int busy_loop(FILE * input) /* return exit status if called with "-c" */ if (input == NULL && WIFEXITED(status)) return WEXITSTATUS(status); - + return 0; } @@ -1534,7 +1561,7 @@ void free_memory(void) static void setup_job_control(void) { int status; - + /* Loop until we are in the foreground. */ while ((status = tcgetpgrp (shell_terminal)) >= 0) { if (status == (shell_pgrp = getpgrp ())) { @@ -1580,7 +1607,7 @@ int lash_main(int argc_l, char **argv_l) prof_input = fopen("/etc/profile", "r"); if (prof_input) { int tmp_fd = fileno(prof_input); - mark_open(tmp_fd); + mark_open(tmp_fd); /* Now run the file */ busy_loop(prof_input); fclose(prof_input); @@ -1644,6 +1671,6 @@ int lash_main(int argc_l, char **argv_l) #else PS1 = NULL; #endif - + return (busy_loop(input)); } |