Fix the code for establishing a controlling terminal.

-Erik
This commit is contained in:
Eric Andersen
2001-06-25 22:24:38 +00:00
parent 24982c589b
commit 6c947d289f
2 changed files with 88 additions and 60 deletions

74
hush.c
View File

@@ -251,7 +251,7 @@ static const char *cwd;
static struct pipe *job_list; static struct pipe *job_list;
static unsigned int last_bg_pid; static unsigned int last_bg_pid;
static unsigned int last_jobid; static unsigned int last_jobid;
static unsigned int ctty; static unsigned int shell_terminal;
static char *PS1; static char *PS1;
static char *PS2; static char *PS2;
struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 }; struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 };
@@ -570,11 +570,9 @@ static int builtin_fg_bg(struct child_prog *child)
if (*child->argv[0] == 'f') { if (*child->argv[0] == 'f') {
/* Make this job the foreground job */ /* Make this job the foreground job */
signal(SIGTTOU, SIG_IGN);
/* suppress messages when run from /linuxrc mag@sysgo.de */ /* suppress messages when run from /linuxrc mag@sysgo.de */
if (tcsetpgrp(ctty, pi->pgrp) && errno != ENOTTY) if (tcsetpgrp(shell_terminal, pi->pgrp) && errno != ENOTTY)
perror_msg("tcsetpgrp-1"); perror_msg("tcsetpgrp-1");
signal(SIGTTOU, SIG_DFL);
} }
/* Restart the processes in the job */ /* Restart the processes in the job */
@@ -1263,7 +1261,7 @@ static int checkjobs(struct pipe* fg_pipe)
perror_msg("waitpid"); perror_msg("waitpid");
/* move the shell to the foreground */ /* move the shell to the foreground */
if (interactive && tcsetpgrp(ctty, getpgid(0))) if (interactive && tcsetpgrp(shell_terminal, getpgid(0)))
perror_msg("tcsetpgrp-2"); perror_msg("tcsetpgrp-2");
return -1; return -1;
} }
@@ -1271,24 +1269,24 @@ static int checkjobs(struct pipe* fg_pipe)
/* Figure out our controlling tty, checking in order stderr, /* Figure out our controlling tty, checking in order stderr,
* stdin, and stdout. If check_pgrp is set, also check that * stdin, and stdout. If check_pgrp is set, also check that
* we belong to the foreground process group associated with * we belong to the foreground process group associated with
* that tty. The value of ctty is needed in order to call * that tty. The value of shell_terminal is needed in order to call
* tcsetpgrp(ctty, ...); */ * tcsetpgrp(shell_terminal, ...); */
void controlling_tty(int check_pgrp) void controlling_tty(int check_pgrp)
{ {
pid_t curpgrp; pid_t curpgrp;
if ((curpgrp = tcgetpgrp(ctty = 2)) < 0 if ((curpgrp = tcgetpgrp(shell_terminal = 2)) < 0
&& (curpgrp = tcgetpgrp(ctty = 0)) < 0 && (curpgrp = tcgetpgrp(shell_terminal = 0)) < 0
&& (curpgrp = tcgetpgrp(ctty = 1)) < 0) && (curpgrp = tcgetpgrp(shell_terminal = 1)) < 0)
goto ctty_error; goto shell_terminal_error;
if (check_pgrp && curpgrp != getpgid(0)) if (check_pgrp && curpgrp != getpgid(0))
goto ctty_error; goto shell_terminal_error;
return; return;
ctty_error: shell_terminal_error:
ctty = -1; shell_terminal = -1;
return; return;
} }
@@ -1402,7 +1400,13 @@ static int run_pipe_real(struct pipe *pi)
/* XXX test for failed fork()? */ /* XXX test for failed fork()? */
if (!(child->pid = 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(SIGTTOU, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
close_all(); close_all();
@@ -1429,9 +1433,7 @@ static int run_pipe_real(struct pipe *pi)
pi->pgrp = getpid(); pi->pgrp = getpid();
} }
if (setpgid(0, pi->pgrp) == 0) { if (setpgid(0, pi->pgrp) == 0) {
signal(SIGTTOU, SIG_IGN);
tcsetpgrp(2, pi->pgrp); tcsetpgrp(2, pi->pgrp);
signal(SIGTTOU, SIG_DFL);
} }
} }
@@ -1489,11 +1491,11 @@ static int run_list_real(struct pipe *pi)
} else { } else {
if (interactive) { if (interactive) {
/* move the new process group into the foreground */ /* 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"); perror_msg("tcsetpgrp-3");
rcode = checkjobs(pi); rcode = checkjobs(pi);
/* move the shell to the foreground */ /* 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"); perror_msg("tcsetpgrp-4");
} else { } else {
rcode = checkjobs(pi); rcode = checkjobs(pi);
@@ -2534,21 +2536,33 @@ static void sigchld_handler(int sig)
signal(SIGCHLD, sigchld_handler); 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() static void setup_job_control()
{ {
/* If we get started under a job aware app (like bash static pid_t shell_pgrp;
* for example), make sure we are now in charge so we /* Loop until we are in the foreground. */
* don't fight over who gets the foreground */ while (tcgetpgrp (shell_terminal) != (shell_pgrp = getpgrp ()))
/* don't pay any attention to this signal; it just confuses kill (- shell_pgrp, SIGTTIN);
things and isn't really meant for shells anyway */
setpgrp();
controlling_tty(0);
signal(SIGTTOU, SIG_IGN);
setpgid(0, getpid());
tcsetpgrp(ctty, getpid());
signal(SIGCHLD, sigchld_handler);
}
/* 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);
signal(SIGCHLD, sigchld_handler);
/* Put ourselves in our own process group. */
shell_pgrp = getpid ();
if (setpgid (shell_pgrp, shell_pgrp) < 0) {
perror_msg_and_die("Couldn't put the shell in its own process group");
}
/* Grab control of the terminal. */
tcsetpgrp(shell_terminal, shell_pgrp);
}
int shell_main(int argc, char **argv) int shell_main(int argc, char **argv)
{ {

View File

@@ -251,7 +251,7 @@ static const char *cwd;
static struct pipe *job_list; static struct pipe *job_list;
static unsigned int last_bg_pid; static unsigned int last_bg_pid;
static unsigned int last_jobid; static unsigned int last_jobid;
static unsigned int ctty; static unsigned int shell_terminal;
static char *PS1; static char *PS1;
static char *PS2; static char *PS2;
struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 }; struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 };
@@ -570,11 +570,9 @@ static int builtin_fg_bg(struct child_prog *child)
if (*child->argv[0] == 'f') { if (*child->argv[0] == 'f') {
/* Make this job the foreground job */ /* Make this job the foreground job */
signal(SIGTTOU, SIG_IGN);
/* suppress messages when run from /linuxrc mag@sysgo.de */ /* suppress messages when run from /linuxrc mag@sysgo.de */
if (tcsetpgrp(ctty, pi->pgrp) && errno != ENOTTY) if (tcsetpgrp(shell_terminal, pi->pgrp) && errno != ENOTTY)
perror_msg("tcsetpgrp-1"); perror_msg("tcsetpgrp-1");
signal(SIGTTOU, SIG_DFL);
} }
/* Restart the processes in the job */ /* Restart the processes in the job */
@@ -1263,7 +1261,7 @@ static int checkjobs(struct pipe* fg_pipe)
perror_msg("waitpid"); perror_msg("waitpid");
/* move the shell to the foreground */ /* move the shell to the foreground */
if (interactive && tcsetpgrp(ctty, getpgid(0))) if (interactive && tcsetpgrp(shell_terminal, getpgid(0)))
perror_msg("tcsetpgrp-2"); perror_msg("tcsetpgrp-2");
return -1; return -1;
} }
@@ -1271,24 +1269,24 @@ static int checkjobs(struct pipe* fg_pipe)
/* Figure out our controlling tty, checking in order stderr, /* Figure out our controlling tty, checking in order stderr,
* stdin, and stdout. If check_pgrp is set, also check that * stdin, and stdout. If check_pgrp is set, also check that
* we belong to the foreground process group associated with * we belong to the foreground process group associated with
* that tty. The value of ctty is needed in order to call * that tty. The value of shell_terminal is needed in order to call
* tcsetpgrp(ctty, ...); */ * tcsetpgrp(shell_terminal, ...); */
void controlling_tty(int check_pgrp) void controlling_tty(int check_pgrp)
{ {
pid_t curpgrp; pid_t curpgrp;
if ((curpgrp = tcgetpgrp(ctty = 2)) < 0 if ((curpgrp = tcgetpgrp(shell_terminal = 2)) < 0
&& (curpgrp = tcgetpgrp(ctty = 0)) < 0 && (curpgrp = tcgetpgrp(shell_terminal = 0)) < 0
&& (curpgrp = tcgetpgrp(ctty = 1)) < 0) && (curpgrp = tcgetpgrp(shell_terminal = 1)) < 0)
goto ctty_error; goto shell_terminal_error;
if (check_pgrp && curpgrp != getpgid(0)) if (check_pgrp && curpgrp != getpgid(0))
goto ctty_error; goto shell_terminal_error;
return; return;
ctty_error: shell_terminal_error:
ctty = -1; shell_terminal = -1;
return; return;
} }
@@ -1402,7 +1400,13 @@ static int run_pipe_real(struct pipe *pi)
/* XXX test for failed fork()? */ /* XXX test for failed fork()? */
if (!(child->pid = 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(SIGTTOU, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
close_all(); close_all();
@@ -1429,9 +1433,7 @@ static int run_pipe_real(struct pipe *pi)
pi->pgrp = getpid(); pi->pgrp = getpid();
} }
if (setpgid(0, pi->pgrp) == 0) { if (setpgid(0, pi->pgrp) == 0) {
signal(SIGTTOU, SIG_IGN);
tcsetpgrp(2, pi->pgrp); tcsetpgrp(2, pi->pgrp);
signal(SIGTTOU, SIG_DFL);
} }
} }
@@ -1489,11 +1491,11 @@ static int run_list_real(struct pipe *pi)
} else { } else {
if (interactive) { if (interactive) {
/* move the new process group into the foreground */ /* 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"); perror_msg("tcsetpgrp-3");
rcode = checkjobs(pi); rcode = checkjobs(pi);
/* move the shell to the foreground */ /* 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"); perror_msg("tcsetpgrp-4");
} else { } else {
rcode = checkjobs(pi); rcode = checkjobs(pi);
@@ -2534,21 +2536,33 @@ static void sigchld_handler(int sig)
signal(SIGCHLD, sigchld_handler); 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() static void setup_job_control()
{ {
/* If we get started under a job aware app (like bash static pid_t shell_pgrp;
* for example), make sure we are now in charge so we /* Loop until we are in the foreground. */
* don't fight over who gets the foreground */ while (tcgetpgrp (shell_terminal) != (shell_pgrp = getpgrp ()))
/* don't pay any attention to this signal; it just confuses kill (- shell_pgrp, SIGTTIN);
things and isn't really meant for shells anyway */
setpgrp();
controlling_tty(0);
signal(SIGTTOU, SIG_IGN);
setpgid(0, getpid());
tcsetpgrp(ctty, getpid());
signal(SIGCHLD, sigchld_handler);
}
/* 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);
signal(SIGCHLD, sigchld_handler);
/* Put ourselves in our own process group. */
shell_pgrp = getpid ();
if (setpgid (shell_pgrp, shell_pgrp) < 0) {
perror_msg_and_die("Couldn't put the shell in its own process group");
}
/* Grab control of the terminal. */
tcsetpgrp(shell_terminal, shell_pgrp);
}
int shell_main(int argc, char **argv) int shell_main(int argc, char **argv)
{ {