diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-06-25 22:24:38 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-06-25 22:24:38 +0000 |
commit | 6c947d289fde9468092a23ed686632c81f99dcac (patch) | |
tree | 2379ef22d461dad0bb5cd3153dcc527885d77ba4 | |
parent | 24982c589bcd53a3f38b868ca17fa12d4922e5ed (diff) | |
download | busybox-w32-6c947d289fde9468092a23ed686632c81f99dcac.tar.gz busybox-w32-6c947d289fde9468092a23ed686632c81f99dcac.tar.bz2 busybox-w32-6c947d289fde9468092a23ed686632c81f99dcac.zip |
Fix the code for establishing a controlling terminal.
-Erik
-rw-r--r-- | hush.c | 70 | ||||
-rw-r--r-- | shell/hush.c | 70 |
2 files changed, 84 insertions, 56 deletions
@@ -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 | { |
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 | { |