我正在学习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
中没有输出。我的问题是
我的代码有什么问题?是什么导致了上述两个问题?
答案 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()
排除与文件关联的文件。