aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-05-17 00:14:27 +0000
committerEric Andersen <andersen@codepoet.org>2001-05-17 00:14:27 +0000
commitbfae2529b8aa7b12b19da2ec7ad00ba717941074 (patch)
tree975962b521c9e653e63f065fa1ac731f88bbd744
parent2439a5982876ef4c8ec7291e156e73f244775ba8 (diff)
downloadbusybox-bfae2529b8aa7b12b19da2ec7ad00ba717941074.tar.gz
It turns out job control in both hush and lash was broken by the
signal handling in cmdedit.c. Disabling it makes the shells behave themselves again. hush isn't quite there, but is getting close... -Erik
-rw-r--r--cmdedit.c4
-rw-r--r--hush.c32
-rw-r--r--shell/cmdedit.c4
-rw-r--r--shell/hush.c32
4 files changed, 52 insertions, 20 deletions
diff --git a/cmdedit.c b/cmdedit.c
index ec9939312..cc39e562a 100644
--- a/cmdedit.c
+++ b/cmdedit.c
@@ -571,6 +571,7 @@ extern void cmdedit_init(void)
atexit(cmdedit_reset_term); /* be sure to do this only once */
}
+#if 0
if ((handlers_sets & SET_TERM_HANDLERS) == 0) {
signal(SIGKILL, clean_up_and_die);
signal(SIGINT, clean_up_and_die);
@@ -578,6 +579,7 @@ extern void cmdedit_init(void)
signal(SIGTERM, clean_up_and_die);
handlers_sets |= SET_TERM_HANDLERS;
}
+#endif
}
@@ -1487,6 +1489,7 @@ prepare_to_die:
extern void cmdedit_terminate(void)
{
cmdedit_reset_term();
+#if 0
if ((handlers_sets & SET_TERM_HANDLERS) != 0) {
signal(SIGKILL, SIG_DFL);
signal(SIGINT, SIG_DFL);
@@ -1495,6 +1498,7 @@ extern void cmdedit_terminate(void)
signal(SIGWINCH, SIG_DFL);
handlers_sets &= ~SET_TERM_HANDLERS;
}
+#endif
}
#endif /* BB_FEATURE_COMMAND_EDITING */
diff --git a/hush.c b/hush.c
index c938fb1e3..59568189f 100644
--- a/hush.c
+++ b/hush.c
@@ -1160,6 +1160,7 @@ static void insert_bg_job(struct pipe *pi)
/* physically copy the struct job */
memcpy(thejob, pi, sizeof(struct pipe));
thejob->next = NULL;
+ //thejob->num_progs = 0;
thejob->running_progs = thejob->num_progs;
thejob->stopped_progs = 0;
thejob->text = xmalloc(MAX_LINE);
@@ -1184,7 +1185,6 @@ static void remove_bg_job(struct pipe *pi)
{
struct pipe *prev_pipe;
- free_pipe(pi);
if (pi == job_list->head) {
job_list->head = pi->next;
} else {
@@ -1194,6 +1194,7 @@ static void remove_bg_job(struct pipe *pi)
prev_pipe->next = pi->next;
}
+ free_pipe(pi);
free(pi);
}
@@ -1393,13 +1394,11 @@ static int run_pipe_real(struct pipe *pi)
setup_redirects(child,NULL);
if (pi->followup!=PIPE_BG) {
- /* Put our child in the process group whose leader is the
- * first process in this pipe. */
+ /* If we (the child) win the race, put ourselves in the process
+ * group whose leader is the first process in this pipe. */
if (pi->pgrp < 0) {
pi->pgrp = child->pid;
}
- /* Don't check for errors. The child may be dead already,
- * in which case setpgid returns error code EACCES. */
if (setpgid(0, pi->pgrp) == 0) {
signal(SIGTTOU, SIG_IGN);
tcsetpgrp(ctty, pi->pgrp);
@@ -1460,15 +1459,11 @@ static int run_list_real(struct pipe *pi)
if (interactive) {
/* move the new process group into the foreground */
/* suppress messages when run from /linuxrc mag@sysgo.de */
- //signal(SIGTTIN, SIG_IGN);
- //signal(SIGTTOU, SIG_IGN);
if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY)
perror_msg("tcsetpgrp");
rcode = pipe_wait(pi);
if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY)
perror_msg("tcsetpgrp");
- //signal(SIGTTIN, SIG_DFL);
- //signal(SIGTTOU, SIG_DFL);
} else {
rcode = pipe_wait(pi);
}
@@ -1479,7 +1474,6 @@ 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;
- /* return rcode; */ /* XXX broken if list is part of if/then/else */
}
checkjobs();
return rcode;
@@ -2528,9 +2522,27 @@ int shell_main(int argc, char **argv)
global_argc = argc;
global_argv = argv;
+ /* 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 */
+ do {
+ pid_t initialpgrp;
+ initialpgrp = tcgetpgrp(fileno(stderr));
+ if (initialpgrp < 0) {
+ error_msg_and_die("sh: can't access tty; job control disabled\n");
+ }
+ if (initialpgrp == -1)
+ initialpgrp = getpgrp();
+ else if (initialpgrp != getpgrp()) {
+ killpg(initialpgrp, SIGTTIN);
+ continue;
+ }
+ } while (0);
/* don't pay any attention to this signal; it just confuses
things and isn't really meant for shells anyway */
signal(SIGTTOU, SIG_IGN);
+ setpgid(0, getpid());
+ tcsetpgrp(fileno(stderr), getpid());
if (argv[0] && argv[0][0] == '-') {
debug_printf("\nsourcing /etc/profile\n");
diff --git a/shell/cmdedit.c b/shell/cmdedit.c
index ec9939312..cc39e562a 100644
--- a/shell/cmdedit.c
+++ b/shell/cmdedit.c
@@ -571,6 +571,7 @@ extern void cmdedit_init(void)
atexit(cmdedit_reset_term); /* be sure to do this only once */
}
+#if 0
if ((handlers_sets & SET_TERM_HANDLERS) == 0) {
signal(SIGKILL, clean_up_and_die);
signal(SIGINT, clean_up_and_die);
@@ -578,6 +579,7 @@ extern void cmdedit_init(void)
signal(SIGTERM, clean_up_and_die);
handlers_sets |= SET_TERM_HANDLERS;
}
+#endif
}
@@ -1487,6 +1489,7 @@ prepare_to_die:
extern void cmdedit_terminate(void)
{
cmdedit_reset_term();
+#if 0
if ((handlers_sets & SET_TERM_HANDLERS) != 0) {
signal(SIGKILL, SIG_DFL);
signal(SIGINT, SIG_DFL);
@@ -1495,6 +1498,7 @@ extern void cmdedit_terminate(void)
signal(SIGWINCH, SIG_DFL);
handlers_sets &= ~SET_TERM_HANDLERS;
}
+#endif
}
#endif /* BB_FEATURE_COMMAND_EDITING */
diff --git a/shell/hush.c b/shell/hush.c
index c938fb1e3..59568189f 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -1160,6 +1160,7 @@ static void insert_bg_job(struct pipe *pi)
/* physically copy the struct job */
memcpy(thejob, pi, sizeof(struct pipe));
thejob->next = NULL;
+ //thejob->num_progs = 0;
thejob->running_progs = thejob->num_progs;
thejob->stopped_progs = 0;
thejob->text = xmalloc(MAX_LINE);
@@ -1184,7 +1185,6 @@ static void remove_bg_job(struct pipe *pi)
{
struct pipe *prev_pipe;
- free_pipe(pi);
if (pi == job_list->head) {
job_list->head = pi->next;
} else {
@@ -1194,6 +1194,7 @@ static void remove_bg_job(struct pipe *pi)
prev_pipe->next = pi->next;
}
+ free_pipe(pi);
free(pi);
}
@@ -1393,13 +1394,11 @@ static int run_pipe_real(struct pipe *pi)
setup_redirects(child,NULL);
if (pi->followup!=PIPE_BG) {
- /* Put our child in the process group whose leader is the
- * first process in this pipe. */
+ /* If we (the child) win the race, put ourselves in the process
+ * group whose leader is the first process in this pipe. */
if (pi->pgrp < 0) {
pi->pgrp = child->pid;
}
- /* Don't check for errors. The child may be dead already,
- * in which case setpgid returns error code EACCES. */
if (setpgid(0, pi->pgrp) == 0) {
signal(SIGTTOU, SIG_IGN);
tcsetpgrp(ctty, pi->pgrp);
@@ -1460,15 +1459,11 @@ static int run_list_real(struct pipe *pi)
if (interactive) {
/* move the new process group into the foreground */
/* suppress messages when run from /linuxrc mag@sysgo.de */
- //signal(SIGTTIN, SIG_IGN);
- //signal(SIGTTOU, SIG_IGN);
if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY)
perror_msg("tcsetpgrp");
rcode = pipe_wait(pi);
if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY)
perror_msg("tcsetpgrp");
- //signal(SIGTTIN, SIG_DFL);
- //signal(SIGTTOU, SIG_DFL);
} else {
rcode = pipe_wait(pi);
}
@@ -1479,7 +1474,6 @@ 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;
- /* return rcode; */ /* XXX broken if list is part of if/then/else */
}
checkjobs();
return rcode;
@@ -2528,9 +2522,27 @@ int shell_main(int argc, char **argv)
global_argc = argc;
global_argv = argv;
+ /* 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 */
+ do {
+ pid_t initialpgrp;
+ initialpgrp = tcgetpgrp(fileno(stderr));
+ if (initialpgrp < 0) {
+ error_msg_and_die("sh: can't access tty; job control disabled\n");
+ }
+ if (initialpgrp == -1)
+ initialpgrp = getpgrp();
+ else if (initialpgrp != getpgrp()) {
+ killpg(initialpgrp, SIGTTIN);
+ continue;
+ }
+ } while (0);
/* don't pay any attention to this signal; it just confuses
things and isn't really meant for shells anyway */
signal(SIGTTOU, SIG_IGN);
+ setpgid(0, getpid());
+ tcsetpgrp(fileno(stderr), getpid());
if (argv[0] && argv[0][0] == '-') {
debug_printf("\nsourcing /etc/profile\n");