Cut-n-paste strikes again
[oweals/busybox.git] / shell / lash.c
index 3675d21dfb95eb64273cec06d40f9959fb9d1ec7..f454e699084beb1afda05b521a7a54d1c13c5451 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * lash -- the BusyBox Lame-Ass SHell
  *
- * Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org>
+ * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
  *
  * Based in part on ladsh.c by Michael K. Johnson and Erik W. Troan, which is
  * under the following liberal license: "We have placed this source code in the
@@ -58,6 +58,7 @@
 
 /* Always enable for the moment... */
 #define CONFIG_LASH_PIPE_N_REDIRECTS
+#define CONFIG_LASH_JOB_CONTROL
 
 static const int MAX_READ = 128;       /* size of input buffer for `read' builtin */
 #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
@@ -192,7 +193,6 @@ static int last_return_code;
 static int last_bg_pid;
 static unsigned int last_jobid;
 static int shell_terminal;
-static pid_t shell_pgrp;
 static char *PS1;
 static char *PS2 = "> ";
 
@@ -513,6 +513,7 @@ static void close_all()
 }
 
 
+#ifdef CONFIG_LASH_JOB_CONTROL
 /* free up all memory from a job */
 static void free_job(struct job *cmd)
 {
@@ -609,6 +610,17 @@ static void checkjobs(struct jobset *j_list)
        if (childpid == -1 && errno != ECHILD)
                bb_perror_msg("waitpid");
 }
+#else
+static void checkjobs(struct jobset *j_list)
+{
+}
+static void free_job(struct job *cmd)
+{
+}
+static void remove_job(struct jobset *j_list, struct job *job)
+{
+}
+#endif
 
 #ifdef CONFIG_LASH_PIPE_N_REDIRECTS
 /* squirrel != NULL means we squirrel away copies of stdin, stdout,
@@ -644,6 +656,7 @@ static int setup_redirects(struct child_prog *prog, int squirrel[])
                if (openfd != redir->fd) {
                        if (squirrel && redir->fd < 3) {
                                squirrel[redir->fd] = dup(redir->fd);
+                               fcntl (squirrel[redir->fd], F_SETFD, FD_CLOEXEC);
                        }
                        dup2(openfd, redir->fd);
                        close(openfd);
@@ -915,7 +928,7 @@ static int expand_arguments(char *command)
 
                }
                if (var) {
-                       /* a single character construction was found, and 
+                       /* a single character construction was found, and
                         * already handled in the case statement */
                        src=dst+2;
                } else {
@@ -1081,7 +1094,7 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg)
 
                                prog->redirects[i].fd = -1;
                                if (buf != prog->argv[argc_l]) {
-                                       /* the stuff before this character may be the file number 
+                                       /* the stuff before this character may be the file number
                                           being redirected */
                                        prog->redirects[i].fd =
                                                strtol(prog->argv[argc_l], &chptr, 10);
@@ -1171,8 +1184,10 @@ static int parse_command(char **command_ptr, struct job *job, int *inbg)
                                break;
 #endif
 
+#ifdef CONFIG_LASH_JOB_CONTROL
                        case '&':                       /* background */
                                *inbg = 1;
+#endif
                        case ';':                       /* multiple commands */
                                done = 1;
                                return_command = *command_ptr + (src - *command_ptr) + 1;
@@ -1261,15 +1276,6 @@ static int pseudo_exec(struct child_prog *child)
         */
        name = child->argv[0];
 
-#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
-        * /bin/cat exists on the filesystem and is _not_ busybox.
-        * Some systems want this, others do not.  Choose wisely.  :-)
-        */
-       name = bb_get_last_path_component(name);
-#endif
-
        {
            char** argv_l=child->argv;
            int argc_l;
@@ -1312,6 +1318,7 @@ static void insert_job(struct job *newjob, int inbg)
        thejob->running_progs = thejob->num_progs;
        thejob->stopped_progs = 0;
 
+#ifdef CONFIG_LASH_JOB_CONTROL
        if (inbg) {
                /* we don't wait for background thejobs to return -- append it
                   to the list of backgrounded thejobs and leave it alone */
@@ -1327,6 +1334,7 @@ static void insert_job(struct job *newjob, int inbg)
                if (tcsetpgrp(shell_terminal, newjob->pgrp) && errno != ENOTTY)
                        bb_perror_msg("tcsetpgrp");
        }
+#endif
 }
 
 static int run_command(struct job *newjob, int inbg, int outpipe[2])
@@ -1373,7 +1381,7 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
                        }
                }
 
-#if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__)
+#if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__)
                if (!(child->pid = fork()))
 #else
                if (!(child->pid = vfork()))
@@ -1438,15 +1446,16 @@ static int busy_loop(FILE * input)
        char *command;
        char *next_command = NULL;
        struct job newjob;
-       pid_t  parent_pgrp;
        int i;
        int inbg;
        int status;
-       newjob.job_list = &job_list;
-       newjob.job_context = DEFAULT_CONTEXT;
-
+#ifdef CONFIG_LASH_JOB_CONTROL
+       pid_t  parent_pgrp;
        /* save current owner of TTY so we can restore it on exit */
        parent_pgrp = tcgetpgrp(shell_terminal);
+#endif
+       newjob.job_list = &job_list;
+       newjob.job_context = DEFAULT_CONTEXT;
 
        command = (char *) xcalloc(BUFSIZ, sizeof(char));
 
@@ -1506,7 +1515,9 @@ static int busy_loop(FILE * input)
                                        remove_job(&job_list, job_list.fg);
                                        job_list.fg = NULL;
                                }
-                       } else {
+                       }
+#ifdef CONFIG_LASH_JOB_CONTROL
+                       else {
                                /* the child was stopped */
                                job_list.fg->stopped_progs++;
                                job_list.fg->progs[i].is_stopped = 1;
@@ -1524,13 +1535,16 @@ static int busy_loop(FILE * input)
                                if (tcsetpgrp(shell_terminal, getpgrp()) && errno != ENOTTY)
                                        bb_perror_msg("tcsetpgrp");
                        }
+#endif
                }
        }
        free(command);
 
+#ifdef CONFIG_LASH_JOB_CONTROL
        /* return controlling TTY back to parent process group before exiting */
        if (tcsetpgrp(shell_terminal, parent_pgrp) && errno != ENOTTY)
                bb_perror_msg("tcsetpgrp");
+#endif
 
        /* return exit status if called with "-c" */
        if (input == NULL && WIFEXITED(status))
@@ -1539,7 +1553,6 @@ static int busy_loop(FILE * input)
        return 0;
 }
 
-
 #ifdef CONFIG_FEATURE_CLEAN_UP
 void free_memory(void)
 {
@@ -1555,12 +1568,14 @@ void free_memory(void)
 }
 #endif
 
+#ifdef CONFIG_LASH_JOB_CONTROL
 /* Make sure we have a controlling tty.  If we get started under a job
  * aware app (like bash for example), make sure we are now in charge so
  * we don't fight over who gets the foreground */
 static void setup_job_control(void)
 {
        int status;
+       pid_t shell_pgrp;
 
        /* Loop until we are in the foreground.  */
        while ((status = tcgetpgrp (shell_terminal)) >= 0) {
@@ -1586,6 +1601,11 @@ static void setup_job_control(void)
        /* Grab control of the terminal.  */
        tcsetpgrp(shell_terminal, shell_pgrp);
 }
+#else
+static inline void setup_job_control(void)
+{
+}
+#endif
 
 int lash_main(int argc_l, char **argv_l)
 {
@@ -1640,14 +1660,14 @@ int lash_main(int argc_l, char **argv_l)
         *    standard output is a terminal
         *    Refer to Posix.2, the description of the `sh' utility. */
        if (argv[optind]==NULL && input==stdin &&
-                       isatty(fileno(stdin)) && isatty(fileno(stdout))) {
+                       isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
                interactive=TRUE;
        }
        setup_job_control();
        if (interactive==TRUE) {
                //printf( "optind=%d  argv[optind]='%s'\n", optind, argv[optind]);
                /* Looks like they want an interactive shell */
-#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET 
+#ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
                printf( "\n\n" BB_BANNER " Built-in shell (lash)\n");
                printf( "Enter 'help' for a list of built-in commands.\n\n");
 #endif