在UNIX环境中创建守护进程

时间:2019-05-19 03:39:35

标签: c linux fork systems-programming

我从APUE中选择了以下示例:

void daemonize(const char* cmd)
{
        int i,fd0,fd1,fd2;
        pid_t pid;
        struct rlimit r1;
        struct sigaction sa;

        //clear all file masks
        umask(0);

        //get max number of file descriptors
        if(getrlimit(RLIMIT_NOFILE,&r1) < 0)
        {
                perror("error getting file descriptor size");
                return;
        }

        //become a session leader
        if((pid = fork()) < 0)
        {
                perror("error forking");
                return;
        }
        else if(pid == 0)
        {
                setsid();
        }
        else
        {
                exit(0); //parent exits
        }

        sa.sa_handler = SIG_IGN;
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = 0;
        if(sigaction(SIGHUP,&sa,NULL) < 0)
        {
                return;
        }

        if((pid = fork()) < 0)
        {
                return;
        }
        else if(pid != 0)
        {
                exit(0); //parent
        }

        //child continues

        syslog(LOG_ERR,"chile continuing with pid : %d",getpid());
        //change the working directory
        if(chdir("/") < 0)
        {
                return;
        }

        if(r1.rlim_max == RLIM_INFINITY)
                r1.rlim_max = 1024;
        for(i=0;i<r1.rlim_max;i++)
                close(i);

        //attach the file descriptors 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\n",fd0,fd1,fd2);
                exit(1);
        }
}


int main()
{
        daemonize("date");
        pause();    //how is this working???
}

我不明白主函数pause()是如何工作的?我期望的是,由于我们已经为exit(0)中的父进程完成了daemonize(),所以它应该已经退出并导致main()进程的正常终止。它应该永远不会返回到main(),并且甚至不会发生对pause()的调用。为什么它没有终止以及为什么叫pause()

1 个答案:

答案 0 :(得分:3)

该代码分叉两次,产生一个父级,一个子级和一个孙子级。前两个exit(0);最后返回的是daemonize