X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=shell%2Fhush.c;h=b74b9d159b8da9cb2ff478227f8e3726b64f9a90;hb=ab6526c8b3d0d38bec62b181276380c0533a151d;hp=fa01d91350141b201dcaadd8f379915ebce74986;hpb=52a97ca00cf5d290c9beb65ba7c217a5ed69ee42;p=oweals%2Fbusybox.git diff --git a/shell/hush.c b/shell/hush.c index fa01d9135..b74b9d159 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -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;