首页 > 解决方案 > 在 UNIX 环境中创建守护进程

问题描述

我从 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()from main 函数是如何工作的?我所期待的是,由于我们已经exit(0)为 中的父进程完成了操作daemonize(),它应该已经退出并导致 main() 进程正常终止。它应该永远不会返回到main()并且调用pause()甚至不应该发生。为什么它没有终止以及为什么pause()被调用?

标签: clinuxforksystems-programming

解决方案


代码分叉了两次,产生了父母、孩子和孙子。前两个exit(0);最后从daemonize.


推荐阅读