一个进程的守护进程?

时间:2014-02-01 05:11:54

标签: c process

我正在学习apue,我尝试根据apue中的代码示例守护进程。代码如下:

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

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

    umask(0);

    if(getrlimit(RLIMIT_NOFILE, &rl) < 0)
    {
        return 1;
    }

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

    setsid();

    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;

    if(sigaction(SIGHUP, &sa, NULL) < 0)
    {
        return 3;
    }

    if((pid = fork()) < 0)
    {
        return 4;
    }
    else if(pid > 0)
    {
        exit(0);
    }

    if(chdir("/") < 0)
    {
        return 5;
    }

    if(rl.rlim_max == RLIM_INFINITY)
    {
        rl.rlim_max = 1024;
    }

    for(i = 0; i < rl.rlim_max; i++)
    {
        close(i);
    }

    fd0 = open("/dev/null", O_RDWR);
    fd1 = dup(0);
    fd2 = dup(0);

    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);
        return 6;
    }
}

int main(void)
{
    FILE *fp;
    int id;
    fp = fopen("test.txt", "w+");
    id = damonize("ls");
    fprintf(fp, "%d", id);
    fclose(fp);
    exit(0);
}

我运行上面的程序并使用ps -axj,但程序没有创建守护进程,并且文件test.txt中没有输出。我的问题是

我的代码有什么问题?是什么导致了上述两个问题?

2 个答案:

答案 0 :(得分:0)

我担心你的课程过于复杂(如果英语中有这样的单词)。你正在产生一个子进程,退出父母,然后孩子产生另一个孩子并退出。然后,孩子的孩子关闭所有可能的(甚至没有打开的)文件描述符,然后打开“/ dev / null”并重定向标准输入,输出和错误。 “daemonisation”已完成,程序会尝试将一些数字写入main函数中的“fp”文件中。但是,fp很久以前已关闭此daemonize

换句话说,主要问题是你的daemonize函数正在关闭循环中所有可能的文件描述符:

for(i = 0; i < rl.rlim_max; i++) close(i);

但是,如果您想要守护进程,为什么不从一个简单的解决方案开始,一旦它工作,您可以添加功能,同时保持其工作。例如,如果您从:

开始
int daemonize() {
    pid_t   pid;

    pid = fork();  
    if (pid > 0) exit(EXIT_SUCCESS);
    if (pid < 0) printf("Can't fork\n");
    return(pid);
}

然后,您可以在close(STDIN_FILENO);之前添加用于关闭标准输入return的代码,依此类推。每次修改测试后,如果它仍在工作。

答案 1 :(得分:0)

你不会看到守护进程,因为它不会留下来。在尝试写入文件后,它会退出。

但是它不会写入文件,因为你的daemonize例程会关闭每个文件句柄(这就是fopen()使用的内容)。尝试在main()之后在daemonize()中打开文件,或者在关闭所有文件描述符的循环中,使用fileno()排除与文件关联的文件。