daemon

下面的代码给出了如何创建一个守护进程。

这个是没有sleep的结果

$./daemon
father              : pid = 22957, ppid = 10927, pgrp = 22957, sid = 10927, tpgrp = 22957
child before setsid : pid = 22958, ppid = 22957, pgrp = 22957, sid = 10927 , tpgrp = 22957
child after setsid  : pid = 22958 , ppid = 22957, pgrp = 22958, sid = 22958 , tpgrp = -1
grand son           : pid = 22959, ppid = 22958, pgrp = 22958, sid = 22958, tpgrp = -1
下面是sleep的结果

$./daemon
father              : pid = 22978, ppid = 10927, pgrp = 22978, sid = 10927, tpgrp = 22978
child before setsid : pid = 22979, ppid = 1, pgrp = 22978, sid = 10927, tpgrp = 10927
child after setsid  : pid = 22979, ppid = 1, pgrp = 22979, sid = 22979, tpgrp = -1
grand son           : pid = 22980, ppid = 22979, pgrp = 22979, sid = 22979, tpgrp = -1


1. 可以看出setsid后,sid变成了当前进程的pid。

2. setsid后,tpgrp已经是-1,表示没有controlling terminal 了

 

 

#include <syslog.h>
#include <fcntl.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <termios.h>

#include <unistd.h>

static void pr_ids(char *name)
{
    printf("%-20s: pid = %d, ppid = %d, pgrp = %d, sid = %d, tpgrp = %d/n",
            name , getpid(), getppid(), getpgrp(), getsid(0), tcgetpgrp(STDIN_FILENO));
    fflush(stdout);
}

void
daemonize(const char *cmd)
{
    int                 i, fd0, fd1, fd2;
    pid_t               pid;
    struct rlimit       rl;
    struct sigaction    sa;
    /*
     * Clear file creation mask.
     */
    umask(0);

    /*
     * Get maximum number of file descriptors.
     */
    if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
        printf("%s: can't get file limit", cmd);

    pr_ids("father");
    /*
     * Become a session leader to lose controlling TTY.
     */
    if ((pid = fork()) < 0)
        printf("%s: can't fork", cmd);
    else if (pid != 0) /* parent */
        exit(0);
    sleep(1);
    pr_ids("child before setsid");
    setsid ();
    pr_ids("child after setsid");

    /*
     * Ensure future opens won't allocate controlling TTYs .
     */
    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGHUP, &sa, NULL) < 0)
        printf("%s: can't ignore SIGHUP");
    if ((pid = fork()) < 0)
        printf("%s: can't fork", cmd);
    else if (pid != 0) /* parent */
        exit(0);

    pr_ids("grand son ");
    /*
     * Change the current working directory to the root so
     * we won't prevent file systems from being unmounted .
     */
    if (chdir("/") < 0)
        printf("%s: can't change directory to /");

    /*
     * Close all open file descriptors.
     */
    if (rl.rlim_max == RLIM_INFINITY)
        rl.rlim_max = 1024;
    for (i = 0; i < rl.rlim_max; i++)
        close(i);

    /*
     * Attach file descriptors 0, 1, and 2 to /dev/null.
     */
    fd0 = open("/dev/null", O_RDWR);
    fd1 = dup(0);
    fd2 = dup(0);

    /*
     * Initialize the log file.
     */
    openlog(cmd, LOG_CONS, LOG_DAEMON);
    if (fd0 != 0 || fd1 != 1 || fd2 != 2) {
        syslog(LOG_ERR, "unexpected file descriptors %d %d %d",
          fd0, fd1, fd2);
        exit(1);
    }
}


int main()
{
    daemonize("test");
    printf("life/n");
    return 0;
}

你可能感兴趣的:(struct,session,File,cmd,null,Terminal)