summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-07-03 11:08:10 +0000
committerEric Andersen <andersen@codepoet.org>2002-07-03 11:08:10 +0000
commit599e3ce163c43c3dfb24d06f8f707c783bc9ab9c (patch)
tree309378de5168889bcfe2bd65704167c47f59da20
parent935daf2d0d65edacfafe32868174c6c634bd35c3 (diff)
downloadbusybox-w32-599e3ce163c43c3dfb24d06f8f707c783bc9ab9c.tar.gz
busybox-w32-599e3ce163c43c3dfb24d06f8f707c783bc9ab9c.tar.bz2
busybox-w32-599e3ce163c43c3dfb24d06f8f707c783bc9ab9c.zip
Apply last_patch47 from vodz to fix several problems, such as the ash "job
control turned off" bug, console_setup() was called with a closed file descriptor, setsid() inconsistancy, and silly string handling bugs. I have modified his patch to allow the askfirst init actions to have a controlling terminal.
-rw-r--r--init/init.c55
1 files changed, 31 insertions, 24 deletions
diff --git a/init/init.c b/init/init.c
index 8b68a0556..4724ad7d5 100644
--- a/init/init.c
+++ b/init/init.c
@@ -484,15 +484,11 @@ static pid_t run(struct init_action *a)
484 if ((pid = fork()) == 0) 484 if ((pid = fork()) == 0)
485 { 485 {
486 /* Clean up */ 486 /* Clean up */
487 ioctl(0, TIOCNOTTY, 0);
488 close(0); 487 close(0);
489 close(1); 488 close(1);
490 close(2); 489 close(2);
491 sigprocmask(SIG_SETMASK, &omask, NULL); 490 sigprocmask(SIG_SETMASK, &omask, NULL);
492 491
493 /* Create a new session and make ourself the process group leader */
494 setsid();
495
496 /* Reset signal handlers that were set by the parent process */ 492 /* Reset signal handlers that were set by the parent process */
497 signal(SIGUSR1, SIG_DFL); 493 signal(SIGUSR1, SIG_DFL);
498 signal(SIGUSR2, SIG_DFL); 494 signal(SIGUSR2, SIG_DFL);
@@ -503,6 +499,11 @@ static pid_t run(struct init_action *a)
503 signal(SIGSTOP, SIG_DFL); 499 signal(SIGSTOP, SIG_DFL);
504 signal(SIGTSTP, SIG_DFL); 500 signal(SIGTSTP, SIG_DFL);
505 501
502 /* Create a new session and make ourself the process
503 * group leader for non-interactive jobs */
504 if ((a->action & (RESPAWN))==0)
505 setsid();
506
506 /* Open the new terminal device */ 507 /* Open the new terminal device */
507 if ((fd = device_open(a->terminal, O_RDWR|O_NOCTTY)) < 0) { 508 if ((fd = device_open(a->terminal, O_RDWR|O_NOCTTY)) < 0) {
508 if (stat(a->terminal, &sb) != 0) { 509 if (stat(a->terminal, &sb) != 0) {
@@ -513,19 +514,26 @@ static pid_t run(struct init_action *a)
513 message(LOG | CONSOLE, "\rBummer, can't open %s\n", a->terminal); 514 message(LOG | CONSOLE, "\rBummer, can't open %s\n", a->terminal);
514 _exit(1); 515 _exit(1);
515 } 516 }
517
518 /* Non-interactive jobs should not get a controling tty */
519 if ((a->action & (RESPAWN))==0)
520 (void)ioctl(fd, TIOCSCTTY, 0);
521
516 /* Make sure the terminal will act fairly normal for us */ 522 /* Make sure the terminal will act fairly normal for us */
517 set_term(0); 523 set_term(0);
524 /* Setup stdin, stdout, stderr for the new process so
525 * they point to the supplied terminal */
526 dup(fd);
527 dup(fd);
518 528
519 /* If the init Action requires up to wait, then force the 529 /* For interactive jobs, create a new session
520 * supplied terminal to be the controlling tty. */ 530 * and become the process group leader */
521 if (a->action & (SYSINIT|WAIT|CTRLALTDEL|SHUTDOWN|RESTART|ASKFIRST)) { 531 if ((a->action & (RESPAWN)))
532 setsid();
522 533
523 /* Take over the controlling tty */ 534 /* If the init Action requires us to wait, then force the
524 ioctl(fd, TIOCSCTTY, 1); 535 * supplied terminal to be the controlling tty. */
525 /* Setup stdin, stdout, stderr for the new process so 536 if (a->action & (SYSINIT|WAIT|CTRLALTDEL|SHUTDOWN|RESTART)) {
526 * they point to the supplied terminal */
527 dup(fd);
528 dup(fd);
529 537
530 /* Now fork off another process to just hang around */ 538 /* Now fork off another process to just hang around */
531 if ((pid = fork()) < 0) { 539 if ((pid = fork()) < 0) {
@@ -542,13 +550,11 @@ static pid_t run(struct init_action *a)
542 signal(SIGCHLD, SIG_DFL); 550 signal(SIGCHLD, SIG_DFL);
543 551
544 /* Wait for child to exit */ 552 /* Wait for child to exit */
545 while ((tmp_pid = waitpid(pid, &junk, 0)) != pid) { 553 while ((tmp_pid = waitpid(pid, &junk, 0)) != pid)
546 if (tmp_pid < 0 && errno == ECHILD) 554 ;
547 break;
548 }
549 555
550 /* See if stealing the controlling tty back is necessary */ 556 /* See if stealing the controlling tty back is necessary */
551 pgrp = tcgetpgrp(tmp_pid); 557 pgrp = tcgetpgrp(fd);
552 if (pgrp != getpid()) 558 if (pgrp != getpid())
553 _exit(0); 559 _exit(0);
554 560
@@ -570,9 +576,6 @@ static pid_t run(struct init_action *a)
570 } 576 }
571 577
572 /* Now fall though to actually execute things */ 578 /* Now fall though to actually execute things */
573 } else {
574 dup(fd);
575 dup(fd);
576 } 579 }
577 580
578 /* See if any special /bin/sh requiring characters are present */ 581 /* See if any special /bin/sh requiring characters are present */
@@ -1079,15 +1082,19 @@ extern int init_main(int argc, char **argv)
1079 /* Figure out what kernel this is running */ 1082 /* Figure out what kernel this is running */
1080 kernelVersion = get_kernel_revision(); 1083 kernelVersion = get_kernel_revision();
1081 1084
1085 /* Figure out where the default console should be */
1086 console_init();
1087
1082 /* Close whatever files are open, and reset the console. */ 1088 /* Close whatever files are open, and reset the console. */
1083 close(0); 1089 close(0);
1084 close(1); 1090 close(1);
1085 close(2); 1091 close(2);
1086 1092
1087 /* Figure out where the default console should be */ 1093 if(device_open(console, O_RDWR|O_NOCTTY)==0) {
1088 console_init();
1089
1090 set_term(0); 1094 set_term(0);
1095 close(0);
1096 }
1097
1091 chdir("/"); 1098 chdir("/");
1092 setsid(); 1099 setsid();
1093 1100