home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************
- * lindner
- * 3.2
- * 1993/03/24 20:18:04
- * /home/mudhoney/GopherSrc/CVS/gopher+/gopherd/daemon.c,v
- * $Status: $
- *
- * Paul Lindner, University of Minnesota CIS.
- *
- * Copyright 1991, 1992 by the Regents of the University of Minnesota
- * see the file "Copyright" in the distribution for conditions of use.
- *********************************************************************
- * MODULE: daemon.c
- * Routines to detach from and run as a daemon.
- *********************************************************************
- * Revision History:
- * daemon.c,v
- * Revision 3.2 1993/03/24 20:18:04 lindner
- * Fixes for SCO3.2
- *
- * Revision 3.1.1.1 1993/02/11 18:02:50 lindner
- * Gopher+1.2beta release
- *
- * Revision 1.1 1992/12/10 23:13:27 lindner
- * gopher 1.1 release
- *
- *
- *********************************************************************/
-
- #include "gopherd.h"
-
- #if defined(_AIX) /** AIX needs bsd signals. **/
- #define _BSD
- #endif
-
- /*
- * A BSD style SIGCLD signal handler that can be used by a server
- * that's not interested in its child's exit status, but needs to
- * wait for them, to avoid clogging up the system with zombies.
- *
- * Beware that the calling process may get an interrupted system
- * call when we return, so they had better handle that.
- *
- * (From Stevens pg 82)
- */
-
- #include "Wait.h"
-
- /* some machines don't have SIGCLD defined */
- #ifndef SIGCLD
- #define SIGCLD SIGCHLD
- #endif
-
- #ifdef hpux
- #define TIOCNOTTY _IO('t', 113) /* void tty association */
- #endif
-
- void
- sig_child()
- {
- /*
- * Use the wait3() system call with the WNOHANG option
- */
-
- int pid;
- Portawait status;
-
- while ( (pid = wait3(&status, WNOHANG|WUNTRACED, NULL)) > 0)
- ;
- }
-
-
- #include <stdio.h>
- #include <sys/param.h>
- #include <errno.h>
- extern int errno;
-
- #if defined(SIGTSTP) && !defined(M_XENIX) && !defined(USG)/* True on a BSD system */
- #include <sys/file.h>
- #include <sys/ioctl.h>
- #endif
-
- /*
- * Detach a daemon process from login session context
- */
-
- void
- daemon_start(ignsigcld)
- int ignsigcld; /* Nonzero -> nuke zombie children */
- {
- register int childpid, fd;
-
- /*
- * If we were started by init (process 1) from the /etc/inittab
- * file there's no need to detach.
- */
-
- if (getppid() != 1) {
-
-
-
- #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
- */
-
- /* Need to add defined(TIOCNOTTY) because SCO2.3.2 has SIGTSTP defined
- but is NOT BSD and doesnt have TIOCNOTTY */
- #if defined(SIGTSTP) && !defined(USG) && defined(TIOCNOTTY) /* BSD */
-
- #if defined(hpux) || defined(_SEQUENT_) || defined(_CRAY) || defined(USG)
- setsid();
- #else
- if (setpgrp(0, getpid()) == -1)
- err_sys("can't change process group");
-
- if ( (fd = uopen("/dev/tty", O_RDWR)) >= 0) {
- ioctl(fd, TIOCNOTTY, (char *)NULL); /* lose controlling TTY*/
- close(fd);
- }
- #endif /* hpux et al.*/
-
- #else /* System V */
-
- if (setpgrp() == -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 */
- #endif
-
- } /* End of if test for ppid == 1 */
-
- /** Close any file descriptors **/
-
- for (fd = 0; fd < NOFILE; fd++)
- close(fd);
-
- errno = 0; /* probably set to EBADF from a close */
-
-
- /** Change the current directory to / **/
-
- /* No need for this, since we're already where we want to be */
- /* rchdir("/"); */
-
- /** Clear inherited file mode creation mask. **/
-
- umask(0);
-
- /*
- * See if the caller isn't ineterested in the exit status of its
- * children, and doesn't want to have them become zombies
- */
-
- if (ignsigcld) {
- #if defined(SIGCLD) && !defined(_CRAY) && !defined(USG)
- void sig_child();
-
- signal(SIGCLD, sig_child); /* BSD */
- #else
- signal(SIGCLD, SIG_IGN); /* System V */
- #endif
- }
- }
-