How can I make my server a daemon?

How can I make my server a daemon?

  There are two approaches you can take here.  The first is to use inetd
  to do all the hard work for you.  The second is to do all the hard
  work yourself.

  If you use inetd, you simply use stdin, stdout, or stderr for your
  socket.  (These three are all created with dup() from the real socket)
  You can use these as you would a socket in your code.  The inetd
  process will even close the socket for you when you are done.

  If you wish to write your own server, there is a detailed explanation
  in "Unix Network Programming" by Richard Stevens (see ``1.5 Where can
  I get source code for the book [book  title]?''). I also picked up
  this posting from comp.unix.programmer, by Nikhil Nair
  (nn201@cus.cam.ac.uk).  You may want to add code to ignore SIGPIPE,
  because if this signal is not dealt with, it will cause your
  application to exit.  (Thanks to ingo@milan2.snafu.de for pointing
  this out).

  I worked all this lot out from the GNU C Library Manual (on-line
  documentation).  Here's some code I wrote - you can adapt it as necessary:

  #include <stdio.h>
  #include <stdlib.h>
  #include <ctype.h>
  #include <unistd.h>
  #include <fcntl.h>
  #include <signal.h>
  #include <sys/wait.h>

  /* Global variables */
  volatile sig_atomic_t keep_going = 1; /* controls program termination */

  /* Function prototypes: */
  void termination_handler (int signum); /* clean up before termination */

  int
  main (void)
  {
    ...

    if (chdir (HOME_DIR))         /* change to directory containing data
                                      files */
     {
       fprintf (stderr, "`%s': ", HOME_DIR);
       perror (NULL);
       exit (1);
     }

     /* Become a daemon: */
     switch (fork ())
       {
       case -1:                    /* can't fork */
         perror ("fork()");
         exit (3);
       case 0:                     /* child, process becomes a daemon: */
         close (STDIN_FILENO);
         close (STDOUT_FILENO);
         close (STDERR_FILENO);
         if (setsid () == -1)      /* request a new session (job control) */
           {
             exit (4);
           }
         break;
       default:                    /* parent returns to calling process: */
         return 0;
       }

     /* Establish signal handler to clean up before termination: */
     if (signal (SIGTERM, termination_handler) == SIG_IGN)
       signal (SIGTERM, SIG_IGN);
     signal (SIGINT, SIG_IGN);
     signal (SIGHUP, SIG_IGN);

     /* Main program loop */
     while (keep_going)
       {
         ...
       }
     return 0;
  }

  void
  termination_handler (int signum)
  {
    keep_going = 0;
    signal (signum, termination_handler);
  }



Home
FAQ