我正在学习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中也没有输出。我的问题是
我的代码出了什么问题?是什么导致了上述两个问题?
发布于 2014-02-01 17:35:34
我担心您的程序过于复杂(如果英语中存在这样的单词)。您正在派生一个子进程,退出父进程,然后子进程派生另一个子进程并退出。孩子的孩子关闭所有可能的(甚至没有打开的)文件描述符,然后打开"/dev/null“,并将标准输入、输出和错误重定向到那里。“守护进程”已经完成,你的程序试图在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);
}然后,可以在return之前添加关闭标准输入close(STDIN_FILENO);的代码,依此类推。在每次修改之后,测试它是否仍在工作。
发布于 2014-02-01 17:37:27
您将看不到守护进程,因为它不会持续存在。在尝试写入文件后,它会退出。
但是它不会写入文件,因为守护例程关闭了每个文件句柄(这是fopen()在幕后使用的)。尝试在daemonize()之后在main()中打开该文件,或者在关闭所有文件描述符的循环中,使用fileno()排除与该文件相关联的文件。
https://stackoverflow.com/questions/21494355
复制相似问题