首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >进程的守护进程?

进程的守护进程?
EN

Stack Overflow用户
提问于 2014-02-01 13:11:54
回答 2查看 365关注 0票数 0

我正在学习apue,并且我尝试根据apue中的代码样本来守护进程。代码如下:

代码语言:javascript
复制
#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中也没有输出。我的问题是

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

EN

回答 2

Stack Overflow用户

发布于 2014-02-01 17:35:34

我担心您的程序过于复杂(如果英语中存在这样的单词)。您正在派生一个子进程,退出父进程,然后子进程派生另一个子进程并退出。孩子的孩子关闭所有可能的(甚至没有打开的)文件描述符,然后打开"/dev/null“,并将标准输入、输出和错误重定向到那里。“守护进程”已经完成,你的程序试图在main函数的文件"fp“中写入一些数字。但是,这个fpdaemonize中很久以前就被关闭了。

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

代码语言:javascript
复制
for(i = 0; i < rl.rlim_max; i++) close(i);

然而,如果你想守护一个进程,为什么不从一个简单的解决方案开始,一旦它工作了,你可以在保持它工作的同时添加功能。例如,如果您从以下位置开始:

代码语言:javascript
复制
int daemonize() {
    pid_t   pid;

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

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

票数 0
EN

Stack Overflow用户

发布于 2014-02-01 17:37:27

您将看不到守护进程,因为它不会持续存在。在尝试写入文件后,它会退出。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21494355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档