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-w32-bfae2529b8aa7b12b19da2ec7ad00ba717941074.tar.gz
busybox-w32-bfae2529b8aa7b12b19da2ec7ad00ba717941074.tar.bz2
busybox-w32-bfae2529b8aa7b12b19da2ec7ad00ba717941074.zip
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)
571 atexit(cmdedit_reset_term); /* be sure to do this only once */ 571 atexit(cmdedit_reset_term); /* be sure to do this only once */
572 } 572 }
573 573
574#if 0
574 if ((handlers_sets & SET_TERM_HANDLERS) == 0) { 575 if ((handlers_sets & SET_TERM_HANDLERS) == 0) {
575 signal(SIGKILL, clean_up_and_die); 576 signal(SIGKILL, clean_up_and_die);
576 signal(SIGINT, clean_up_and_die); 577 signal(SIGINT, clean_up_and_die);
@@ -578,6 +579,7 @@ extern void cmdedit_init(void)
578 signal(SIGTERM, clean_up_and_die); 579 signal(SIGTERM, clean_up_and_die);
579 handlers_sets |= SET_TERM_HANDLERS; 580 handlers_sets |= SET_TERM_HANDLERS;
580 } 581 }
582#endif
581 583
582} 584}
583 585
@@ -1487,6 +1489,7 @@ prepare_to_die:
1487extern void cmdedit_terminate(void) 1489extern void cmdedit_terminate(void)
1488{ 1490{
1489 cmdedit_reset_term(); 1491 cmdedit_reset_term();
1492#if 0
1490 if ((handlers_sets & SET_TERM_HANDLERS) != 0) { 1493 if ((handlers_sets & SET_TERM_HANDLERS) != 0) {
1491 signal(SIGKILL, SIG_DFL); 1494 signal(SIGKILL, SIG_DFL);
1492 signal(SIGINT, SIG_DFL); 1495 signal(SIGINT, SIG_DFL);
@@ -1495,6 +1498,7 @@ extern void cmdedit_terminate(void)
1495 signal(SIGWINCH, SIG_DFL); 1498 signal(SIGWINCH, SIG_DFL);
1496 handlers_sets &= ~SET_TERM_HANDLERS; 1499 handlers_sets &= ~SET_TERM_HANDLERS;
1497 } 1500 }
1501#endif
1498} 1502}
1499 1503
1500#endif /* BB_FEATURE_COMMAND_EDITING */ 1504#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)
1160 /* physically copy the struct job */ 1160 /* physically copy the struct job */
1161 memcpy(thejob, pi, sizeof(struct pipe)); 1161 memcpy(thejob, pi, sizeof(struct pipe));
1162 thejob->next = NULL; 1162 thejob->next = NULL;
1163 //thejob->num_progs = 0;
1163 thejob->running_progs = thejob->num_progs; 1164 thejob->running_progs = thejob->num_progs;
1164 thejob->stopped_progs = 0; 1165 thejob->stopped_progs = 0;
1165 thejob->text = xmalloc(MAX_LINE); 1166 thejob->text = xmalloc(MAX_LINE);
@@ -1184,7 +1185,6 @@ static void remove_bg_job(struct pipe *pi)
1184{ 1185{
1185 struct pipe *prev_pipe; 1186 struct pipe *prev_pipe;
1186 1187
1187 free_pipe(pi);
1188 if (pi == job_list->head) { 1188 if (pi == job_list->head) {
1189 job_list->head = pi->next; 1189 job_list->head = pi->next;
1190 } else { 1190 } else {
@@ -1194,6 +1194,7 @@ static void remove_bg_job(struct pipe *pi)
1194 prev_pipe->next = pi->next; 1194 prev_pipe->next = pi->next;
1195 } 1195 }
1196 1196
1197 free_pipe(pi);
1197 free(pi); 1198 free(pi);
1198} 1199}
1199 1200
@@ -1393,13 +1394,11 @@ static int run_pipe_real(struct pipe *pi)
1393 setup_redirects(child,NULL); 1394 setup_redirects(child,NULL);
1394 1395
1395 if (pi->followup!=PIPE_BG) { 1396 if (pi->followup!=PIPE_BG) {
1396 /* Put our child in the process group whose leader is the 1397 /* If we (the child) win the race, put ourselves in the process
1397 * first process in this pipe. */ 1398 * group whose leader is the first process in this pipe. */
1398 if (pi->pgrp < 0) { 1399 if (pi->pgrp < 0) {
1399 pi->pgrp = child->pid; 1400 pi->pgrp = child->pid;
1400 } 1401 }
1401 /* Don't check for errors. The child may be dead already,
1402 * in which case setpgid returns error code EACCES. */
1403 if (setpgid(0, pi->pgrp) == 0) { 1402 if (setpgid(0, pi->pgrp) == 0) {
1404 signal(SIGTTOU, SIG_IGN); 1403 signal(SIGTTOU, SIG_IGN);
1405 tcsetpgrp(ctty, pi->pgrp); 1404 tcsetpgrp(ctty, pi->pgrp);
@@ -1460,15 +1459,11 @@ static int run_list_real(struct pipe *pi)
1460 if (interactive) { 1459 if (interactive) {
1461 /* move the new process group into the foreground */ 1460 /* move the new process group into the foreground */
1462 /* suppress messages when run from /linuxrc mag@sysgo.de */ 1461 /* suppress messages when run from /linuxrc mag@sysgo.de */
1463 //signal(SIGTTIN, SIG_IGN);
1464 //signal(SIGTTOU, SIG_IGN);
1465 if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY) 1462 if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY)
1466 perror_msg("tcsetpgrp"); 1463 perror_msg("tcsetpgrp");
1467 rcode = pipe_wait(pi); 1464 rcode = pipe_wait(pi);
1468 if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY) 1465 if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY)
1469 perror_msg("tcsetpgrp"); 1466 perror_msg("tcsetpgrp");
1470 //signal(SIGTTIN, SIG_DFL);
1471 //signal(SIGTTOU, SIG_DFL);
1472 } else { 1467 } else {
1473 rcode = pipe_wait(pi); 1468 rcode = pipe_wait(pi);
1474 } 1469 }
@@ -1479,7 +1474,6 @@ static int run_list_real(struct pipe *pi)
1479 if ( (rcode==EXIT_SUCCESS && pi->followup==PIPE_OR) || 1474 if ( (rcode==EXIT_SUCCESS && pi->followup==PIPE_OR) ||
1480 (rcode!=EXIT_SUCCESS && pi->followup==PIPE_AND) ) 1475 (rcode!=EXIT_SUCCESS && pi->followup==PIPE_AND) )
1481 skip_more_in_this_rmode=rmode; 1476 skip_more_in_this_rmode=rmode;
1482 /* return rcode; */ /* XXX broken if list is part of if/then/else */
1483 } 1477 }
1484 checkjobs(); 1478 checkjobs();
1485 return rcode; 1479 return rcode;
@@ -2528,9 +2522,27 @@ int shell_main(int argc, char **argv)
2528 global_argc = argc; 2522 global_argc = argc;
2529 global_argv = argv; 2523 global_argv = argv;
2530 2524
2525 /* If we get started under a job aware app (like bash
2526 * for example), make sure we are now in charge so we
2527 * don't fight over who gets the foreground */
2528 do {
2529 pid_t initialpgrp;
2530 initialpgrp = tcgetpgrp(fileno(stderr));
2531 if (initialpgrp < 0) {
2532 error_msg_and_die("sh: can't access tty; job control disabled\n");
2533 }
2534 if (initialpgrp == -1)
2535 initialpgrp = getpgrp();
2536 else if (initialpgrp != getpgrp()) {
2537 killpg(initialpgrp, SIGTTIN);
2538 continue;
2539 }
2540 } while (0);
2531 /* don't pay any attention to this signal; it just confuses 2541 /* don't pay any attention to this signal; it just confuses
2532 things and isn't really meant for shells anyway */ 2542 things and isn't really meant for shells anyway */
2533 signal(SIGTTOU, SIG_IGN); 2543 signal(SIGTTOU, SIG_IGN);
2544 setpgid(0, getpid());
2545 tcsetpgrp(fileno(stderr), getpid());
2534 2546
2535 if (argv[0] && argv[0][0] == '-') { 2547 if (argv[0] && argv[0][0] == '-') {
2536 debug_printf("\nsourcing /etc/profile\n"); 2548 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)
571 atexit(cmdedit_reset_term); /* be sure to do this only once */ 571 atexit(cmdedit_reset_term); /* be sure to do this only once */
572 } 572 }
573 573
574#if 0
574 if ((handlers_sets & SET_TERM_HANDLERS) == 0) { 575 if ((handlers_sets & SET_TERM_HANDLERS) == 0) {
575 signal(SIGKILL, clean_up_and_die); 576 signal(SIGKILL, clean_up_and_die);
576 signal(SIGINT, clean_up_and_die); 577 signal(SIGINT, clean_up_and_die);
@@ -578,6 +579,7 @@ extern void cmdedit_init(void)
578 signal(SIGTERM, clean_up_and_die); 579 signal(SIGTERM, clean_up_and_die);
579 handlers_sets |= SET_TERM_HANDLERS; 580 handlers_sets |= SET_TERM_HANDLERS;
580 } 581 }
582#endif
581 583
582} 584}
583 585
@@ -1487,6 +1489,7 @@ prepare_to_die:
1487extern void cmdedit_terminate(void) 1489extern void cmdedit_terminate(void)
1488{ 1490{
1489 cmdedit_reset_term(); 1491 cmdedit_reset_term();
1492#if 0
1490 if ((handlers_sets & SET_TERM_HANDLERS) != 0) { 1493 if ((handlers_sets & SET_TERM_HANDLERS) != 0) {
1491 signal(SIGKILL, SIG_DFL); 1494 signal(SIGKILL, SIG_DFL);
1492 signal(SIGINT, SIG_DFL); 1495 signal(SIGINT, SIG_DFL);
@@ -1495,6 +1498,7 @@ extern void cmdedit_terminate(void)
1495 signal(SIGWINCH, SIG_DFL); 1498 signal(SIGWINCH, SIG_DFL);
1496 handlers_sets &= ~SET_TERM_HANDLERS; 1499 handlers_sets &= ~SET_TERM_HANDLERS;
1497 } 1500 }
1501#endif
1498} 1502}
1499 1503
1500#endif /* BB_FEATURE_COMMAND_EDITING */ 1504#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)
1160 /* physically copy the struct job */ 1160 /* physically copy the struct job */
1161 memcpy(thejob, pi, sizeof(struct pipe)); 1161 memcpy(thejob, pi, sizeof(struct pipe));
1162 thejob->next = NULL; 1162 thejob->next = NULL;
1163 //thejob->num_progs = 0;
1163 thejob->running_progs = thejob->num_progs; 1164 thejob->running_progs = thejob->num_progs;
1164 thejob->stopped_progs = 0; 1165 thejob->stopped_progs = 0;
1165 thejob->text = xmalloc(MAX_LINE); 1166 thejob->text = xmalloc(MAX_LINE);
@@ -1184,7 +1185,6 @@ static void remove_bg_job(struct pipe *pi)
1184{ 1185{
1185 struct pipe *prev_pipe; 1186 struct pipe *prev_pipe;
1186 1187
1187 free_pipe(pi);
1188 if (pi == job_list->head) { 1188 if (pi == job_list->head) {
1189 job_list->head = pi->next; 1189 job_list->head = pi->next;
1190 } else { 1190 } else {
@@ -1194,6 +1194,7 @@ static void remove_bg_job(struct pipe *pi)
1194 prev_pipe->next = pi->next; 1194 prev_pipe->next = pi->next;
1195 } 1195 }
1196 1196
1197 free_pipe(pi);
1197 free(pi); 1198 free(pi);
1198} 1199}
1199 1200
@@ -1393,13 +1394,11 @@ static int run_pipe_real(struct pipe *pi)
1393 setup_redirects(child,NULL); 1394 setup_redirects(child,NULL);
1394 1395
1395 if (pi->followup!=PIPE_BG) { 1396 if (pi->followup!=PIPE_BG) {
1396 /* Put our child in the process group whose leader is the 1397 /* If we (the child) win the race, put ourselves in the process
1397 * first process in this pipe. */ 1398 * group whose leader is the first process in this pipe. */
1398 if (pi->pgrp < 0) { 1399 if (pi->pgrp < 0) {
1399 pi->pgrp = child->pid; 1400 pi->pgrp = child->pid;
1400 } 1401 }
1401 /* Don't check for errors. The child may be dead already,
1402 * in which case setpgid returns error code EACCES. */
1403 if (setpgid(0, pi->pgrp) == 0) { 1402 if (setpgid(0, pi->pgrp) == 0) {
1404 signal(SIGTTOU, SIG_IGN); 1403 signal(SIGTTOU, SIG_IGN);
1405 tcsetpgrp(ctty, pi->pgrp); 1404 tcsetpgrp(ctty, pi->pgrp);
@@ -1460,15 +1459,11 @@ static int run_list_real(struct pipe *pi)
1460 if (interactive) { 1459 if (interactive) {
1461 /* move the new process group into the foreground */ 1460 /* move the new process group into the foreground */
1462 /* suppress messages when run from /linuxrc mag@sysgo.de */ 1461 /* suppress messages when run from /linuxrc mag@sysgo.de */
1463 //signal(SIGTTIN, SIG_IGN);
1464 //signal(SIGTTOU, SIG_IGN);
1465 if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY) 1462 if (tcsetpgrp(0, pi->pgrp) && errno != ENOTTY)
1466 perror_msg("tcsetpgrp"); 1463 perror_msg("tcsetpgrp");
1467 rcode = pipe_wait(pi); 1464 rcode = pipe_wait(pi);
1468 if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY) 1465 if (tcsetpgrp(0, getpgrp()) && errno != ENOTTY)
1469 perror_msg("tcsetpgrp"); 1466 perror_msg("tcsetpgrp");
1470 //signal(SIGTTIN, SIG_DFL);
1471 //signal(SIGTTOU, SIG_DFL);
1472 } else { 1467 } else {
1473 rcode = pipe_wait(pi); 1468 rcode = pipe_wait(pi);
1474 } 1469 }
@@ -1479,7 +1474,6 @@ static int run_list_real(struct pipe *pi)
1479 if ( (rcode==EXIT_SUCCESS && pi->followup==PIPE_OR) || 1474 if ( (rcode==EXIT_SUCCESS && pi->followup==PIPE_OR) ||
1480 (rcode!=EXIT_SUCCESS && pi->followup==PIPE_AND) ) 1475 (rcode!=EXIT_SUCCESS && pi->followup==PIPE_AND) )
1481 skip_more_in_this_rmode=rmode; 1476 skip_more_in_this_rmode=rmode;
1482 /* return rcode; */ /* XXX broken if list is part of if/then/else */
1483 } 1477 }
1484 checkjobs(); 1478 checkjobs();
1485 return rcode; 1479 return rcode;
@@ -2528,9 +2522,27 @@ int shell_main(int argc, char **argv)
2528 global_argc = argc; 2522 global_argc = argc;
2529 global_argv = argv; 2523 global_argv = argv;
2530 2524
2525 /* If we get started under a job aware app (like bash
2526 * for example), make sure we are now in charge so we
2527 * don't fight over who gets the foreground */
2528 do {
2529 pid_t initialpgrp;
2530 initialpgrp = tcgetpgrp(fileno(stderr));
2531 if (initialpgrp < 0) {
2532 error_msg_and_die("sh: can't access tty; job control disabled\n");
2533 }
2534 if (initialpgrp == -1)
2535 initialpgrp = getpgrp();
2536 else if (initialpgrp != getpgrp()) {
2537 killpg(initialpgrp, SIGTTIN);
2538 continue;
2539 }
2540 } while (0);
2531 /* don't pay any attention to this signal; it just confuses 2541 /* don't pay any attention to this signal; it just confuses
2532 things and isn't really meant for shells anyway */ 2542 things and isn't really meant for shells anyway */
2533 signal(SIGTTOU, SIG_IGN); 2543 signal(SIGTTOU, SIG_IGN);
2544 setpgid(0, getpid());
2545 tcsetpgrp(fileno(stderr), getpid());
2534 2546
2535 if (argv[0] && argv[0][0] == '-') { 2547 if (argv[0] && argv[0][0] == '-') {
2536 debug_printf("\nsourcing /etc/profile\n"); 2548 debug_printf("\nsourcing /etc/profile\n");