home *** CD-ROM | disk | FTP | other *** search
- /*
- * Initialize a daemon process.
- */
-
- #include <stdio.h>
- #include <signal.h>
- #include <sys/param.h>
- #include <errno.h>
- #include <unistd.h>
- #include <sys/file.h>
- #include <sys/ioctl.h>
- #include <sys/stat.h>
-
- extern int errno;
- extern void err_sys(char *fmt, ...);
-
- /*
- * Detach a daemon process from login session context.
- */
-
- void
- daemon_start(int ignsigcld)
- /* nonzero -> handle SIGCLDs so zombies don't clog */
- {
- register int childpid, fd;
-
- /*
- * If we were started by init (process 1) from the /etc/inittab file
- * there's no need to detach.
- * This test is unreliable due to an unavoidable ambiguity
- * if the process is started by some other process and orphaned
- * (i.e., if the parent process terminates before we are started).
- */
-
- if (getppid() == 1)
- goto out;
-
- /*
- * Ignore the terminal stop signals (BSD).
- */
-
- #ifdef SIGTTOU
- signal(SIGTTOU, SIG_IGN);
- #endif
- #ifdef SIGTTIN
- signal(SIGTTIN, SIG_IGN);
- #endif
- #ifdef SIGTSTP
- signal(SIGTSTP, SIG_IGN);
- #endif
-
- /*
- * If we were not started in the background, fork and
- * let the parent exit. This also guarantees the first child
- * is not a process group leader.
- */
-
- if ( (childpid = fork()) < 0)
- err_sys("can't fork first child");
- else if (childpid > 0)
- exit(0); /* parent */
-
- /*
- * First child process.
- *
- * Disassociate from controlling terminal and process group.
- * Ensure the process can't reacquire a new controlling terminal.
- */
-
- if (setpgid(0, getpid()) == -1)
- err_sys("can't change process group");
-
- signal(SIGHUP, SIG_IGN); /* immune from pgrp leader death */
-
- if ( (childpid = fork()) < 0)
- err_sys("can't fork second child");
- else if (childpid > 0)
- exit(0); /* first child */
-
- /* second child */
-
- out:
- /*
- * Close any open files descriptors.
- */
-
- for (fd = 0; fd < NOFILE; fd++)
- close(fd);
-
- errno = 0; /* probably got set to EBADF from a close */
-
- /*
- * Move the current directory to root, to make sure we
- * aren't on a mounted filesystem.
- */
-
- chdir("/");
-
- /*
- * Clear any inherited file mode creation mask.
- */
-
- umask(0);
-
- /*
- * See if the caller isn't interested in the exit status of its
- * children, and doesn't want to have them become zombies and
- * clog up the system.
- * With System V all we need do is ignore the signal.
- * With BSD, however, we have to catch each signal
- * and execute the wait3() system call.
- */
-
- if (ignsigcld)
- {
- signal(SIGCLD, SIG_IGN); /* System V */
- }
- }
-