/*
 * 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 <unistd.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;
}

<B>Listing 1.  Daemon start-up code.<B>
