home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / gopher+1.2b4 / gopherd / daemon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-24  |  4.6 KB  |  195 lines

  1. /********************************************************************
  2.  * lindner
  3.  * 3.2
  4.  * 1993/03/24 20:18:04
  5.  * /home/mudhoney/GopherSrc/CVS/gopher+/gopherd/daemon.c,v
  6.  * $Status: $
  7.  *
  8.  * Paul Lindner, University of Minnesota CIS.
  9.  *
  10.  * Copyright 1991, 1992 by the Regents of the University of Minnesota
  11.  * see the file "Copyright" in the distribution for conditions of use.
  12.  *********************************************************************
  13.  * MODULE: daemon.c
  14.  * Routines to detach from and run as a daemon.
  15.  *********************************************************************
  16.  * Revision History:
  17.  * daemon.c,v
  18.  * Revision 3.2  1993/03/24  20:18:04  lindner
  19.  * Fixes for SCO3.2
  20.  *
  21.  * Revision 3.1.1.1  1993/02/11  18:02:50  lindner
  22.  * Gopher+1.2beta release
  23.  *
  24.  * Revision 1.1  1992/12/10  23:13:27  lindner
  25.  * gopher 1.1 release
  26.  *
  27.  *
  28.  *********************************************************************/
  29.  
  30. #include "gopherd.h"
  31.  
  32. #if defined(_AIX)  /** AIX needs bsd signals.  **/
  33. #define _BSD
  34. #endif
  35.  
  36. /*
  37.  * A BSD style SIGCLD signal handler that can be used by a server
  38.  * that's not interested in its child's exit status, but needs to
  39.  * wait for them, to avoid clogging up the system with zombies.
  40.  *
  41.  * Beware that the calling process may get an interrupted system
  42.  * call when we return, so they had better handle that.
  43.  *
  44.  * (From Stevens pg 82)
  45.  */
  46.  
  47. #include "Wait.h"
  48.  
  49. /* some machines don't have SIGCLD defined */
  50. #ifndef SIGCLD
  51. #define SIGCLD        SIGCHLD
  52. #endif
  53.  
  54. #ifdef hpux
  55. #define TIOCNOTTY       _IO('t', 113)           /* void tty association */
  56. #endif
  57.  
  58. void
  59. sig_child()
  60. {
  61.      /*
  62.       * Use the wait3() system call with the WNOHANG option
  63.       */
  64.  
  65.      int pid;
  66.      Portawait status;
  67.  
  68.      while ( (pid = wait3(&status, WNOHANG|WUNTRACED, NULL)) > 0)
  69.       ;
  70. }
  71.  
  72.  
  73. #include <stdio.h>
  74. #include <sys/param.h>
  75. #include <errno.h>
  76. extern int errno;
  77.  
  78. #if defined(SIGTSTP) && !defined(M_XENIX) && !defined(USG)/* True on a BSD system */
  79. #include <sys/file.h>
  80. #include <sys/ioctl.h>
  81. #endif
  82.  
  83. /*
  84.  * Detach a daemon process from login session context
  85.  */
  86.  
  87. void
  88. daemon_start(ignsigcld)
  89.   int ignsigcld;          /* Nonzero -> nuke zombie children */
  90. {
  91.      register int childpid, fd;
  92.  
  93.      /*
  94.       * If we were started by init (process 1) from the /etc/inittab
  95.       * file there's no need to detach.
  96.       */
  97.       
  98.      if (getppid() != 1) {
  99.  
  100.       
  101.  
  102. #ifdef SIGTTOU
  103.       signal(SIGTTOU, SIG_IGN);
  104. #endif
  105. #ifdef SIGTTIN
  106.       signal(SIGTTIN, SIG_IGN);
  107. #endif
  108. #ifdef SIGTSTP
  109.       signal(SIGTSTP, SIG_IGN);
  110. #endif
  111.  
  112.       /*
  113.        * If we were not started in the background, fork and let
  114.        * the parent exit.  This also guarantees the first child
  115.        * is not a process group leader.
  116.        */
  117.  
  118.       if ( (childpid = fork()) < 0)
  119.            err_sys("can't fork first child");
  120.       else if (childpid >0)
  121.            exit(0);     /* parent */
  122.       
  123.       /*
  124.        * First Child process
  125.        *
  126.        * Disassociate from controlling terminal and process group.
  127.        * Ensure the process can't reacquire a new controlling terminal
  128.        */
  129.       
  130. /* Need to add defined(TIOCNOTTY) because SCO2.3.2 has SIGTSTP defined
  131.    but is NOT BSD and doesnt have TIOCNOTTY */
  132. #if defined(SIGTSTP) && !defined(USG) && defined(TIOCNOTTY)  /* BSD */
  133.       
  134. #if defined(hpux) || defined(_SEQUENT_) || defined(_CRAY) || defined(USG)
  135.       setsid();
  136. #else
  137.       if (setpgrp(0, getpid()) == -1)
  138.            err_sys("can't change process group");
  139.       
  140.       if ( (fd = uopen("/dev/tty", O_RDWR)) >= 0) {
  141.            ioctl(fd, TIOCNOTTY, (char *)NULL); /* lose controlling TTY*/
  142.            close(fd);
  143.       }
  144. #endif /* hpux  et al.*/
  145.       
  146. #else /* System V */
  147.       
  148.       if (setpgrp() == -1)
  149.            err_sys("Can't change process group");
  150.       
  151.       signal(SIGHUP, SIG_IGN);  /* immune from pgrp leader death */
  152.       
  153.       if ( (childpid = fork()) < 0)
  154.            err_sys("Can't fork second child");
  155.       else if (childpid > 0)
  156.            exit(0); /* First child */
  157.       
  158.       /* second child */
  159. #endif
  160.  
  161.      }  /* End of if test for ppid == 1 */
  162.  
  163.      /** Close any file descriptors **/
  164.  
  165.      for (fd = 0; fd < NOFILE; fd++)
  166.       close(fd);
  167.  
  168.      errno = 0;  /* probably set to EBADF from a close */
  169.  
  170.  
  171.      /** Change the current directory to / **/
  172.  
  173.      /* No need for this, since we're already where we want to be */
  174.      /* rchdir("/"); */
  175.  
  176.      /** Clear inherited file mode creation mask. **/
  177.  
  178.      umask(0);
  179.  
  180.      /*
  181.       * See if the caller isn't ineterested in the exit status of its
  182.       * children, and doesn't want to have them become zombies
  183.       */
  184.  
  185.      if (ignsigcld) {
  186. #if defined(SIGCLD) && !defined(_CRAY) && !defined(USG)
  187.       void sig_child();
  188.  
  189.       signal(SIGCLD, sig_child);  /* BSD */
  190. #else
  191.       signal(SIGCLD, SIG_IGN);    /* System V */
  192. #endif
  193.      }
  194. }
  195.