Remove debugging statement.
[oweals/busybox.git] / shell / hush.c
index fa01d91350141b201dcaadd8f379915ebce74986..b74b9d159b8da9cb2ff478227f8e3726b64f9a90 100644 (file)
@@ -251,7 +251,7 @@ static const char *cwd;
 static struct pipe *job_list;
 static unsigned int last_bg_pid;
 static unsigned int last_jobid;
-static unsigned int ctty;
+static unsigned int shell_terminal;
 static char *PS1;
 static char *PS2;
 struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 };
@@ -395,7 +395,6 @@ static void remove_bg_job(struct pipe *pi);
 static char *get_local_var(const char *var);
 static void  unset_local_var(const char *name);
 static int set_local_var(const char *s, int flg_export);
-static void sigchld_handler(int sig);
 
 /* Table of built-in functions.  They can be forked or not, depending on
  * context: within pipes, they fork.  As simple commands, they do not.
@@ -569,19 +568,21 @@ static int builtin_fg_bg(struct child_prog *child)
        }
 
        if (*child->argv[0] == 'f') {
-               /* Make this job the foreground job */
-               signal(SIGTTOU, SIG_IGN);
-               /* suppress messages when run from /linuxrc mag@sysgo.de */
-               if (tcsetpgrp(ctty, pi->pgrp) && errno != ENOTTY)
-                       perror_msg("tcsetpgrp-1"); 
-               signal(SIGTTOU, SIG_DFL);
+               /* Put the job into the foreground.  */
+               tcsetpgrp(shell_terminal, pi->pgrp);
        }
 
        /* Restart the processes in the job */
        for (i = 0; i < pi->num_progs; i++)
                pi->progs[i].is_stopped = 0;
 
-       kill(-pi->pgrp, SIGCONT);
+       if ( (i=kill(- pi->pgrp, SIGCONT)) < 0) {
+               if (i == ESRCH) {
+                       remove_bg_job(pi);
+               } else {
+                       perror_msg("kill (SIGCONT)");
+               }
+       }
 
        pi->stopped_progs = 0;
        return EXIT_SUCCESS;
@@ -863,7 +864,7 @@ static inline void setup_prompt_string(int promptmode, char **prompt_str)
                *prompt_str = PS2;
        }
 #else
-       *prompt_str = (promptmode==0)? PS1 : PS2;
+       *prompt_str = (promptmode==1)? PS1 : PS2;
 #endif
        debug_printf("result %s\n",*prompt_str);
 }
@@ -1187,6 +1188,11 @@ static void remove_bg_job(struct pipe *pi)
                        prev_pipe = prev_pipe->next;
                prev_pipe->next = pi->next;
        }
+       if (job_list)
+               last_jobid = job_list->jobid;
+       else
+               last_jobid = 0;
+
        pi->stopped_progs = 0;
        free_pipe(pi, 0);
        free(pi);
@@ -1263,32 +1269,32 @@ static int checkjobs(struct pipe* fg_pipe)
                perror_msg("waitpid");
 
        /* move the shell to the foreground */
-       if (interactive && tcsetpgrp(ctty, getpgid(0)))
-               perror_msg("tcsetpgrp-2");
+       //if (interactive && tcsetpgrp(shell_terminal, getpgid(0)))
+       //      perror_msg("tcsetpgrp-2");
        return -1;
 }
 
 /* Figure out our controlling tty, checking in order stderr,
  * stdin, and stdout.  If check_pgrp is set, also check that
  * we belong to the foreground process group associated with
- * that tty.  The value of ctty is needed in order to call
- * tcsetpgrp(ctty, ...); */
+ * that tty.  The value of shell_terminal is needed in order to call
+ * tcsetpgrp(shell_terminal, ...); */
 void controlling_tty(int check_pgrp)
 {
        pid_t curpgrp;
 
-       if ((curpgrp = tcgetpgrp(ctty = 2)) < 0
-                       && (curpgrp = tcgetpgrp(ctty = 0)) < 0
-                       && (curpgrp = tcgetpgrp(ctty = 1)) < 0)
-               goto ctty_error;
+       if ((curpgrp = tcgetpgrp(shell_terminal = 2)) < 0
+                       && (curpgrp = tcgetpgrp(shell_terminal = 0)) < 0
+                       && (curpgrp = tcgetpgrp(shell_terminal = 1)) < 0)
+               goto shell_terminal_error;
 
        if (check_pgrp && curpgrp != getpgid(0))
-               goto ctty_error;
+               goto shell_terminal_error;
 
        return;
 
-ctty_error:
-               ctty = -1;
+shell_terminal_error:
+               shell_terminal = -1;
                return;
 }
 
@@ -1402,7 +1408,13 @@ static int run_pipe_real(struct pipe *pi)
 
                /* XXX test for failed fork()? */
                if (!(child->pid = fork())) {
+                       /* Set the handling for job control signals back to the default.  */
+                       signal(SIGINT, SIG_DFL);
+                       signal(SIGQUIT, SIG_DFL);
+                       signal(SIGTSTP, SIG_DFL);
+                       signal(SIGTTIN, SIG_DFL);
                        signal(SIGTTOU, SIG_DFL);
+                       signal(SIGCHLD, SIG_DFL);
                        
                        close_all();
 
@@ -1429,9 +1441,7 @@ static int run_pipe_real(struct pipe *pi)
                                        pi->pgrp = getpid();
                                }
                                if (setpgid(0, pi->pgrp) == 0) {
-                                       signal(SIGTTOU, SIG_IGN);
                                        tcsetpgrp(2, pi->pgrp);
-                                       signal(SIGTTOU, SIG_DFL);
                                }
                        }
 
@@ -1489,11 +1499,11 @@ static int run_list_real(struct pipe *pi)
                } else {
                        if (interactive) {
                                /* move the new process group into the foreground */
-                               if (tcsetpgrp(ctty, pi->pgrp) && errno != ENOTTY)
+                               if (tcsetpgrp(shell_terminal, pi->pgrp) && errno != ENOTTY)
                                        perror_msg("tcsetpgrp-3");
                                rcode = checkjobs(pi);
                                /* move the shell to the foreground */
-                               if (tcsetpgrp(ctty, getpgid(0)) && errno != ENOTTY)
+                               if (tcsetpgrp(shell_terminal, getpgid(0)) && errno != ENOTTY)
                                        perror_msg("tcsetpgrp-4");
                        } else {
                                rcode = checkjobs(pi);
@@ -1506,8 +1516,8 @@ static int run_list_real(struct pipe *pi)
                if ( (rcode==EXIT_SUCCESS && pi->followup==PIPE_OR) ||
                     (rcode!=EXIT_SUCCESS && pi->followup==PIPE_AND) )
                        skip_more_in_this_rmode=rmode;
+               checkjobs(NULL);
        }
-       checkjobs(NULL);
        return rcode;
 }
 
@@ -2528,27 +2538,32 @@ static int parse_file_outer(FILE *f)
        return rcode;
 }
 
-static void sigchld_handler(int sig)
-{ 
-       checkjobs(NULL);
-       signal(SIGCHLD, sigchld_handler);
-}
-
+/* 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()
 {
-       /* 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 */
-       /* don't pay any attention to this signal; it just confuses 
-          things and isn't really meant for shells anyway */
-       setpgrp();
-       controlling_tty(0);
+       static pid_t shell_pgrp;
+       /* Loop until we are in the foreground.  */
+       while (tcgetpgrp (shell_terminal) != (shell_pgrp = getpgrp ()))
+               kill (- shell_pgrp, SIGTTIN);
+
+       /* Ignore interactive and job-control signals.  */
+       signal(SIGINT, SIG_IGN);
+       signal(SIGQUIT, SIG_IGN);
+       signal(SIGTSTP, SIG_IGN);
+       signal(SIGTTIN, SIG_IGN);
        signal(SIGTTOU, SIG_IGN);
-       setpgid(0, getpid());
-       tcsetpgrp(ctty, getpid());
-       signal(SIGCHLD, sigchld_handler);
-}
+       signal(SIGCHLD, SIG_IGN);
 
+       /* Put ourselves in our own process group.  */
+       setsid();
+       shell_pgrp = getpid ();
+       setpgid (shell_pgrp, shell_pgrp);
+
+       /* Grab control of the terminal.  */
+       tcsetpgrp(shell_terminal, shell_pgrp);
+}
 
 int shell_main(int argc, char **argv)
 {
@@ -2593,11 +2608,12 @@ int shell_main(int argc, char **argv)
 
        if (argv[0] && argv[0][0] == '-') {
                debug_printf("\nsourcing /etc/profile\n");
-               input = xfopen("/etc/profile", "r");
-               mark_open(fileno(input));
-               parse_file_outer(input);
-               mark_closed(fileno(input));
-               fclose(input);
+               if ((input = fopen("/etc/profile", "r")) != NULL) {
+                       mark_open(fileno(input));
+                       parse_file_outer(input);
+                       mark_closed(fileno(input));
+                       fclose(input);
+               }
        }
        input=stdin;