Support disabling pipe and redirect support
authorEric Andersen <andersen@codepoet.org>
Tue, 10 Feb 2004 01:07:45 +0000 (01:07 -0000)
committerEric Andersen <andersen@codepoet.org>
Tue, 10 Feb 2004 01:07:45 +0000 (01:07 -0000)
shell/lash.c

index 1fcd63bdf5f731d6af2c55257a049a07913daa59..3675d21dfb95eb64273cec06d40f9959fb9d1ec7 100644 (file)
 #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));
 }