diff options
author | Eric Andersen <andersen@codepoet.org> | 2002-07-03 11:08:10 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2002-07-03 11:08:10 +0000 |
commit | 599e3ce163c43c3dfb24d06f8f707c783bc9ab9c (patch) | |
tree | 309378de5168889bcfe2bd65704167c47f59da20 | |
parent | 935daf2d0d65edacfafe32868174c6c634bd35c3 (diff) | |
download | busybox-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.c | 55 |
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 | ||