- if ((pid = fork()) == 0)
- {
- /* Clean up */
- close(0);
- close(1);
- close(2);
- sigprocmask(SIG_SETMASK, &omask, NULL);
-
- /* Reset signal handlers that were set by the parent process */
- signal(SIGUSR1, SIG_DFL);
- signal(SIGUSR2, SIG_DFL);
- signal(SIGINT, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
- signal(SIGHUP, SIG_DFL);
- signal(SIGCONT, SIG_DFL);
- signal(SIGSTOP, SIG_DFL);
- signal(SIGTSTP, SIG_DFL);
-
- /* Create a new session and make ourself the process
- * group leader for non-interactive jobs */
- if ((a->action & (RESPAWN))==0)
- setsid();
-
- /* Open the new terminal device */
- if ((device_open(a->terminal, O_RDWR|O_NOCTTY)) < 0) {
- if (stat(a->terminal, &sb) != 0) {
- message(LOG | CONSOLE, "\rdevice '%s' does not exist.\n",
- a->terminal);
- _exit(1);
- }
- message(LOG | CONSOLE, "\rBummer, can't open %s\n", a->terminal);
- _exit(1);
- }
-
- /* Non-interactive jobs should not get a controling tty */
- if ((a->action & (RESPAWN))==0)
- (void)ioctl(0, TIOCSCTTY, 0);
-
- /* Make sure the terminal will act fairly normal for us */
- set_term(0);
- /* Setup stdout, stderr for the new process so
- * they point to the supplied terminal */
- dup(0);
- dup(0);
-
- /* For interactive jobs, create a new session
- * and become the process group leader */
- if ((a->action & (RESPAWN)))
- setsid();
-
- /* If the init Action requires us to wait, then force the
- * supplied terminal to be the controlling tty. */
- if (a->action & (SYSINIT|WAIT|CTRLALTDEL|SHUTDOWN|RESTART)) {
-
- /* Now fork off another process to just hang around */
- if ((pid = fork()) < 0) {
- message(LOG | CONSOLE, "Can't fork!\n");
- _exit(1);
- }
-
- if (pid > 0) {
-
- /* We are the parent -- wait till the child is done */
- signal(SIGINT, SIG_IGN);
- signal(SIGTSTP, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGCHLD, SIG_DFL);
-
- /* Wait for child to exit */
- while ((tmp_pid = waitpid(pid, &junk, 0)) != pid)
- ;
-
- /* See if stealing the controlling tty back is necessary */
- pgrp = tcgetpgrp(0);
- if (pgrp != getpid())
- _exit(0);
-
- /* Use a temporary process to steal the controlling tty. */
- if ((pid = fork()) < 0) {
- message(LOG | CONSOLE, "\rCan't fork!\n");
- _exit(1);
- }
- if (pid == 0) {
- setsid();
- ioctl(0, TIOCSCTTY, 1);
- _exit(0);
- }
- while((tmp_pid = waitpid(pid, &junk, 0)) != pid) {
- if (tmp_pid < 0 && errno == ECHILD)
- break;
- }
- _exit(0);
- }