home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / src / gopher / gopher1.01 / misc / Radio / radiod / daemon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-13  |  3.5 KB  |  164 lines

  1. /*
  2.  *******************************************************************
  3.  * $Author: lindner $
  4.  * $Revision: 1.1 $
  5.  * $Date: 91/03/25 21:10:22 $
  6.  * $Source: /export/mermaid/staff/lindner/gopherd/RCS/daemon.c,v $
  7.  *******************************************************************
  8.  */
  9.  
  10. #include "gopherd.h"
  11.  
  12. #define BSD 1       /* System V signal handling doesn't seem to work
  13.                Correctly */
  14.  
  15. /*
  16.  * A BSD style SIGCLD signal handler that can be used by a server
  17.  * that's not interested in its child's exit status, but needs to
  18.  * wait for them, to avoid clogging up the system with zombies.
  19.  *
  20.  * Beware that the calling process may get an interrupted system
  21.  * call when we return, so they had better handle that.
  22.  *
  23.  * (From Stevens pg 82)
  24.  */
  25.  
  26. #include <sys/ioctl.h>
  27. #include <sys/wait.h>
  28. #include <signal.h>
  29.  
  30. #ifdef HP9000
  31.   #define TIOCNOTTY       _IO('t', 113)           /* void tty association */
  32. #endif
  33.  
  34. sig_child()
  35. {
  36. #ifdef BSD
  37.      /*
  38.       * Use the wait3() system call with the WNOHANG option
  39.       */
  40.  
  41.      int pid;
  42.      union wait  status;
  43.  
  44.      while ( (pid = wait3(&status, WNOHANG, (struct rusage *) 0)) > 0)
  45.       ;
  46. #endif
  47. }
  48.  
  49.  
  50. #include <stdio.h>
  51. #include <sys/param.h>
  52. #include <errno.h>
  53. extern int errno;
  54.  
  55. #ifdef SIGTSTP    /* True on a BSD system */
  56. #include <sys/file.h>
  57. #include <sys/ioctl.h>
  58. #endif
  59.  
  60. /*
  61.  * Detach a daemon process from login session context
  62.  */
  63.  
  64. daemon_start(ignsigcld)
  65. int ignsigcld;          /* Nonzero -> nuke zombie children */
  66. {
  67.      register int childpid, fd;
  68.  
  69.      /*
  70.       * If we were started by init (process 1) from the /etc/inittab
  71.       * file there's no need to detach.
  72.       */
  73.       
  74.      if (getppid() != 1) {
  75.  
  76.       
  77.  
  78. #ifdef SIGTTOU
  79.       signal(SIGTTOU, SIG_IGN);
  80. #endif
  81. #ifdef SIGTTIN
  82.       signal(SIGTTIN, SIG_IGN);
  83. #endif
  84. #ifdef SIGTSTP
  85.       signal(SIGTSTP, SIG_IGN);
  86. #endif
  87.  
  88.       /*
  89.        * If we were not started in the background, fork and let
  90.        * the parent exit.  This also guarantees the first child
  91.        * is not a process group leader.
  92.        */
  93.  
  94.       if ( (childpid = fork()) < 0)
  95.            err_sys("can't fork first child");
  96.       else if (childpid >0)
  97.            exit(0);     /* parent */
  98.       
  99.       /*
  100.        * First Child process
  101.        *
  102.        * Disassociate from controlling terminal and process group.
  103.        * Ensure the process can't reacquire a new controlling terminal
  104.        */
  105.       
  106. #ifdef SIGTSTP  /* BSD */
  107.  
  108.       if (setpgrp(0, getpid()) == -1)
  109.            err_sys("can't change process group");
  110.       
  111.       if ( (fd = open("/dev/tty", O_RDWR)) >= 0) {
  112.            ioctl(fd, TIOCNOTTY, (char *)NULL); /* lose controlling TTY*/
  113.            close(fd);
  114.       }
  115.       
  116. #else /* System V */
  117.       
  118.       if (setpgrp() == -1)
  119.            err_sys("Can't change process group");
  120.       
  121.       signal(SIGHUP, SIG_IGN);  /* immune from pgrp leader death */
  122.       
  123.       if ( (childpid = fork()) < 0)
  124.            err_sys("Can't fork second child");
  125.       else if (childpid > 0)
  126.            exit(0); /* First child */
  127.       
  128.       /* second child */
  129. #endif
  130.  
  131.      }  /* End of if test for ppid == 1 */
  132.  
  133.      /** Close any file descriptors **/
  134.  
  135.      for (fd = 0; fd < NOFILE; fd++)
  136.       close(fd);
  137.  
  138.      errno = 0;  /* probably set to EBADF from a close */
  139.  
  140.  
  141.      /** Change the current directory to / **/
  142.  
  143.       chdir("/");
  144.  
  145.      /** Clear inherited file mode creation mask. **/
  146.  
  147.      umask(0);
  148.  
  149.      /*
  150.       * See if the caller isn't ineterested in the exit status of its
  151.       * children, and doesn't want to have them become zombies
  152.       */
  153.  
  154.      if (ignsigcld) {
  155. #ifdef SIGTSTP
  156.       int sig_child();
  157.  
  158.       signal(SIGCLD, sig_child);  /* BSD */
  159. #else
  160.       signal(SIGCLD, SIG_IGN);    /* System V */
  161. #endif
  162.      }
  163. }
  164.