diff options
| author | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2001-06-25 22:24:38 +0000 |
|---|---|---|
| committer | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2001-06-25 22:24:38 +0000 |
| commit | c721ee0ea05d9654a39d891c06d8300f833aecfa (patch) | |
| tree | 2379ef22d461dad0bb5cd3153dcc527885d77ba4 /shell | |
| parent | ecab1d9cba60730efd26dfc1cbea4db5548af0b4 (diff) | |
| download | busybox-w32-c721ee0ea05d9654a39d891c06d8300f833aecfa.tar.gz busybox-w32-c721ee0ea05d9654a39d891c06d8300f833aecfa.tar.bz2 busybox-w32-c721ee0ea05d9654a39d891c06d8300f833aecfa.zip | |
Fix the code for establishing a controlling terminal.
-Erik
git-svn-id: svn://busybox.net/trunk/busybox@2901 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 70 |
1 files changed, 42 insertions, 28 deletions
diff --git a/shell/hush.c b/shell/hush.c index fa01d9135..b0637f806 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -251,7 +251,7 @@ static const char *cwd; | |||
| 251 | static struct pipe *job_list; | 251 | static struct pipe *job_list; |
| 252 | static unsigned int last_bg_pid; | 252 | static unsigned int last_bg_pid; |
| 253 | static unsigned int last_jobid; | 253 | static unsigned int last_jobid; |
| 254 | static unsigned int ctty; | 254 | static unsigned int shell_terminal; |
| 255 | static char *PS1; | 255 | static char *PS1; |
| 256 | static char *PS2; | 256 | static char *PS2; |
| 257 | struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 }; | 257 | struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 }; |
| @@ -570,11 +570,9 @@ static int builtin_fg_bg(struct child_prog *child) | |||
| 570 | 570 | ||
| 571 | if (*child->argv[0] == 'f') { | 571 | if (*child->argv[0] == 'f') { |
| 572 | /* Make this job the foreground job */ | 572 | /* Make this job the foreground job */ |
| 573 | signal(SIGTTOU, SIG_IGN); | ||
| 574 | /* suppress messages when run from /linuxrc mag@sysgo.de */ | 573 | /* suppress messages when run from /linuxrc mag@sysgo.de */ |
| 575 | if (tcsetpgrp(ctty, pi->pgrp) && errno != ENOTTY) | 574 | if (tcsetpgrp(shell_terminal, pi->pgrp) && errno != ENOTTY) |
| 576 | perror_msg("tcsetpgrp-1"); | 575 | perror_msg("tcsetpgrp-1"); |
| 577 | signal(SIGTTOU, SIG_DFL); | ||
| 578 | } | 576 | } |
| 579 | 577 | ||
| 580 | /* Restart the processes in the job */ | 578 | /* Restart the processes in the job */ |
| @@ -1263,7 +1261,7 @@ static int checkjobs(struct pipe* fg_pipe) | |||
| 1263 | perror_msg("waitpid"); | 1261 | perror_msg("waitpid"); |
| 1264 | 1262 | ||
| 1265 | /* move the shell to the foreground */ | 1263 | /* move the shell to the foreground */ |
| 1266 | if (interactive && tcsetpgrp(ctty, getpgid(0))) | 1264 | if (interactive && tcsetpgrp(shell_terminal, getpgid(0))) |
| 1267 | perror_msg("tcsetpgrp-2"); | 1265 | perror_msg("tcsetpgrp-2"); |
| 1268 | return -1; | 1266 | return -1; |
| 1269 | } | 1267 | } |
| @@ -1271,24 +1269,24 @@ static int checkjobs(struct pipe* fg_pipe) | |||
| 1271 | /* Figure out our controlling tty, checking in order stderr, | 1269 | /* Figure out our controlling tty, checking in order stderr, |
| 1272 | * stdin, and stdout. If check_pgrp is set, also check that | 1270 | * stdin, and stdout. If check_pgrp is set, also check that |
| 1273 | * we belong to the foreground process group associated with | 1271 | * we belong to the foreground process group associated with |
| 1274 | * that tty. The value of ctty is needed in order to call | 1272 | * that tty. The value of shell_terminal is needed in order to call |
| 1275 | * tcsetpgrp(ctty, ...); */ | 1273 | * tcsetpgrp(shell_terminal, ...); */ |
| 1276 | void controlling_tty(int check_pgrp) | 1274 | void controlling_tty(int check_pgrp) |
| 1277 | { | 1275 | { |
| 1278 | pid_t curpgrp; | 1276 | pid_t curpgrp; |
| 1279 | 1277 | ||
| 1280 | if ((curpgrp = tcgetpgrp(ctty = 2)) < 0 | 1278 | if ((curpgrp = tcgetpgrp(shell_terminal = 2)) < 0 |
| 1281 | && (curpgrp = tcgetpgrp(ctty = 0)) < 0 | 1279 | && (curpgrp = tcgetpgrp(shell_terminal = 0)) < 0 |
| 1282 | && (curpgrp = tcgetpgrp(ctty = 1)) < 0) | 1280 | && (curpgrp = tcgetpgrp(shell_terminal = 1)) < 0) |
| 1283 | goto ctty_error; | 1281 | goto shell_terminal_error; |
| 1284 | 1282 | ||
| 1285 | if (check_pgrp && curpgrp != getpgid(0)) | 1283 | if (check_pgrp && curpgrp != getpgid(0)) |
| 1286 | goto ctty_error; | 1284 | goto shell_terminal_error; |
| 1287 | 1285 | ||
| 1288 | return; | 1286 | return; |
| 1289 | 1287 | ||
| 1290 | ctty_error: | 1288 | shell_terminal_error: |
| 1291 | ctty = -1; | 1289 | shell_terminal = -1; |
| 1292 | return; | 1290 | return; |
| 1293 | } | 1291 | } |
| 1294 | 1292 | ||
| @@ -1402,7 +1400,13 @@ static int run_pipe_real(struct pipe *pi) | |||
| 1402 | 1400 | ||
| 1403 | /* XXX test for failed fork()? */ | 1401 | /* XXX test for failed fork()? */ |
| 1404 | if (!(child->pid = fork())) { | 1402 | if (!(child->pid = fork())) { |
| 1403 | /* Set the handling for job control signals back to the default. */ | ||
| 1404 | signal(SIGINT, SIG_DFL); | ||
| 1405 | signal(SIGQUIT, SIG_DFL); | ||
| 1406 | signal(SIGTSTP, SIG_DFL); | ||
| 1407 | signal(SIGTTIN, SIG_DFL); | ||
| 1405 | signal(SIGTTOU, SIG_DFL); | 1408 | signal(SIGTTOU, SIG_DFL); |
| 1409 | signal(SIGCHLD, SIG_DFL); | ||
| 1406 | 1410 | ||
| 1407 | close_all(); | 1411 | close_all(); |
| 1408 | 1412 | ||
| @@ -1429,9 +1433,7 @@ static int run_pipe_real(struct pipe *pi) | |||
| 1429 | pi->pgrp = getpid(); | 1433 | pi->pgrp = getpid(); |
| 1430 | } | 1434 | } |
| 1431 | if (setpgid(0, pi->pgrp) == 0) { | 1435 | if (setpgid(0, pi->pgrp) == 0) { |
| 1432 | signal(SIGTTOU, SIG_IGN); | ||
| 1433 | tcsetpgrp(2, pi->pgrp); | 1436 | tcsetpgrp(2, pi->pgrp); |
| 1434 | signal(SIGTTOU, SIG_DFL); | ||
| 1435 | } | 1437 | } |
| 1436 | } | 1438 | } |
| 1437 | 1439 | ||
| @@ -1489,11 +1491,11 @@ static int run_list_real(struct pipe *pi) | |||
| 1489 | } else { | 1491 | } else { |
| 1490 | if (interactive) { | 1492 | if (interactive) { |
| 1491 | /* move the new process group into the foreground */ | 1493 | /* move the new process group into the foreground */ |
| 1492 | if (tcsetpgrp(ctty, pi->pgrp) && errno != ENOTTY) | 1494 | if (tcsetpgrp(shell_terminal, pi->pgrp) && errno != ENOTTY) |
| 1493 | perror_msg("tcsetpgrp-3"); | 1495 | perror_msg("tcsetpgrp-3"); |
| 1494 | rcode = checkjobs(pi); | 1496 | rcode = checkjobs(pi); |
| 1495 | /* move the shell to the foreground */ | 1497 | /* move the shell to the foreground */ |
| 1496 | if (tcsetpgrp(ctty, getpgid(0)) && errno != ENOTTY) | 1498 | if (tcsetpgrp(shell_terminal, getpgid(0)) && errno != ENOTTY) |
| 1497 | perror_msg("tcsetpgrp-4"); | 1499 | perror_msg("tcsetpgrp-4"); |
| 1498 | } else { | 1500 | } else { |
| 1499 | rcode = checkjobs(pi); | 1501 | rcode = checkjobs(pi); |
| @@ -2534,21 +2536,33 @@ static void sigchld_handler(int sig) | |||
| 2534 | signal(SIGCHLD, sigchld_handler); | 2536 | signal(SIGCHLD, sigchld_handler); |
| 2535 | } | 2537 | } |
| 2536 | 2538 | ||
| 2539 | /* Make sure we have a controlling tty. If we get started under a job | ||
| 2540 | * aware app (like bash for example), make sure we are now in charge so | ||
| 2541 | * we don't fight over who gets the foreground */ | ||
| 2537 | static void setup_job_control() | 2542 | static void setup_job_control() |
| 2538 | { | 2543 | { |
| 2539 | /* If we get started under a job aware app (like bash | 2544 | static pid_t shell_pgrp; |
| 2540 | * for example), make sure we are now in charge so we | 2545 | /* Loop until we are in the foreground. */ |
| 2541 | * don't fight over who gets the foreground */ | 2546 | while (tcgetpgrp (shell_terminal) != (shell_pgrp = getpgrp ())) |
| 2542 | /* don't pay any attention to this signal; it just confuses | 2547 | kill (- shell_pgrp, SIGTTIN); |
| 2543 | things and isn't really meant for shells anyway */ | 2548 | |
| 2544 | setpgrp(); | 2549 | /* Ignore interactive and job-control signals. */ |
| 2545 | controlling_tty(0); | 2550 | signal(SIGINT, SIG_IGN); |
| 2551 | signal(SIGQUIT, SIG_IGN); | ||
| 2552 | signal(SIGTSTP, SIG_IGN); | ||
| 2553 | signal(SIGTTIN, SIG_IGN); | ||
| 2546 | signal(SIGTTOU, SIG_IGN); | 2554 | signal(SIGTTOU, SIG_IGN); |
| 2547 | setpgid(0, getpid()); | ||
| 2548 | tcsetpgrp(ctty, getpid()); | ||
| 2549 | signal(SIGCHLD, sigchld_handler); | 2555 | signal(SIGCHLD, sigchld_handler); |
| 2550 | } | ||
| 2551 | 2556 | ||
| 2557 | /* Put ourselves in our own process group. */ | ||
| 2558 | shell_pgrp = getpid (); | ||
| 2559 | if (setpgid (shell_pgrp, shell_pgrp) < 0) { | ||
| 2560 | perror_msg_and_die("Couldn't put the shell in its own process group"); | ||
| 2561 | } | ||
| 2562 | |||
| 2563 | /* Grab control of the terminal. */ | ||
| 2564 | tcsetpgrp(shell_terminal, shell_pgrp); | ||
| 2565 | } | ||
| 2552 | 2566 | ||
| 2553 | int shell_main(int argc, char **argv) | 2567 | int shell_main(int argc, char **argv) |
| 2554 | { | 2568 | { |
