LJ Archive

Listing 1. Daemon Start-up Code

/*
 * Listing 1:
 * fork(), closing controlling terminal, changing
 * session group, fork(), change current working
 * directory, set umask
 * Ivan Griffin (ivan.griffin@ul.ie)
 */
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv)
{
    struct rlimit resourceLimit = { 0 };
    int status = -1;
    int fileDesc = -1;
    /*
     * somewhere in the code
     */
    status = fork();
    switch (status)
    {
    case -1:
        perror(fork());
        exit(1);
    case 0: /* child process */
        break;
    default: /* parent process */
        exit(0);
    }
    /*
     * child process
     */
    resourceLimit.rlim_max = 0;
    status = getrlimit(RLIMIT_NOFILE,
   &resourceLimit);
    if (-1 == status) /* shouldn't happen */
    {
        perror(getrlimit());
        exit(1);
    }
    if (0 == resourceLimit.rlim_max)
    {
        fprintf("Max number of open file
      descriptors is 0!!\n");
        exit(1);
    }

    for (i = 0; i < resourceLimit.rlim_max; i++)
    {
        (void) close(i);
    }
    status = setsid();
    if (-1 == status)
    {
        perror(setsid());
        exit(1);
    }
    status = fork();
    switch (status)
    {
    case -1:
        perror("fork()");
        exit(1);
    case 0: /* (second) child process */
        break;
    default: /* parent process */
        exit(0);
    }
    /*
     * now we are in a new session and process
     * group than process that started the
     * daemon. We also have no controlling
     * terminal */
    chdir("/");
    umask(0);
    fileDesc = open("/dev/null", O_RDWR);/* stdin */
    (void) dup(fileDesc);  /* stdout */
    (void) dup(fileDesc);  /* stderr */
    /*
     * the rest of the daemon code executes in
     * this environment
     */
    return 0;
}
LJ Archive