当我创建守护进程时,fopen() 似乎不起作用
fopen() seems not work when I create a daemon process
这是我的主要源代码:
int main(int argc, char *argv[]) {
[...]
if (become_daemon(0) == -1) {
exit(EXIT_FAILURE);
}
while (main_loop == LOOP_CONTINUE) {
[...]
if (log_data(date_temp, data_processed) < 0) {
[...]
} else {
[...]
}
sleep(measure_rate);
}
[...]
}
这里是我的函数定义:
int become_daemon(int flags) {
int maxfd, fd;
switch (fork()) {
case -1:
return -1;
case 0:
break;
default:
exit(EXIT_SUCCESS);
}
if (setsid() == -1)
return -1;
switch (fork()) {
case -1:
return -1;
case 0:
break;
default:
exit(EXIT_SUCCESS);
}
if (!(flags & BD_NO_MASK0))
umask(0);
if (!(flags & BD_NO_CHDIR))
chdir("/");
if (!(flags & BD_NO_CLOSE_FILE)) {
maxfd = sysconf(_SC_OPEN_MAX);
if (maxfd == -1)
maxfd = BD_MAX_CLOSE;
for (fd = 0; fd < maxfd; fd++)
close(fd);
}
if (!(flags & BD_NO_REOPEN_STD_FDS)) {
close(STDIN_FILENO);
fd = open("/dev/null", O_RDWR);
if (fd != STDIN_FILENO)
return -1;
if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO)
return -1;
if (dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO)
return -1;
}
return 0;
}
int log_data(char *date, double array_data[DATA_NUM]) {
FILE *file;
if ((file = fopen(DATALOG_FILE, "a")) == NULL)
return -1;
fprintf(file, "%s ; %.2f ; %.2f ; %.2f ; %.2f ; %.2f ; %.2f\n",
date, array_data[0], array_data[1], array_data[2],
array_data[3], array_data[4], array_data[5]);
fclose(file);
return 0;
}
这是我的问题:
当我使用 become_daemon()
函数编译我的代码并执行程序时,文件 DATALOG_FILE
(它是 "xxxxxx.txt"
的定义)没有创建。如果我在没有 become_daemon()
函数调用的情况下进行编译,则程序可以正常运行并创建文件。
我什至注意到如果我添加行
sudo /my/folder/program
在 rc.local
到 运行 中,它在启动时按我想要的方式启动,但即使在这种情况下,它也不会创建文件 DATALOG_FILE.
我是守护进程的新手所以谁能告诉我这种行为的原因吗?
正如 Ctx 在他的评论中提到的,函数 become_daemon
可能会将当前目录更改为 /
。如果 DATALOG_FILE
是相对文件名,例如您在问题中所写的 "xxxxxx.txt"
,则守护程序将无法在系统根目录中创建它,除非它具有根权限。
要么不通过将 BD_NO_CHDIR
作为参数传递给 become_daemon
来更改当前目录,要么使 DATALOG_FILE
成为绝对路径。
这是我的主要源代码:
int main(int argc, char *argv[]) {
[...]
if (become_daemon(0) == -1) {
exit(EXIT_FAILURE);
}
while (main_loop == LOOP_CONTINUE) {
[...]
if (log_data(date_temp, data_processed) < 0) {
[...]
} else {
[...]
}
sleep(measure_rate);
}
[...]
}
这里是我的函数定义:
int become_daemon(int flags) {
int maxfd, fd;
switch (fork()) {
case -1:
return -1;
case 0:
break;
default:
exit(EXIT_SUCCESS);
}
if (setsid() == -1)
return -1;
switch (fork()) {
case -1:
return -1;
case 0:
break;
default:
exit(EXIT_SUCCESS);
}
if (!(flags & BD_NO_MASK0))
umask(0);
if (!(flags & BD_NO_CHDIR))
chdir("/");
if (!(flags & BD_NO_CLOSE_FILE)) {
maxfd = sysconf(_SC_OPEN_MAX);
if (maxfd == -1)
maxfd = BD_MAX_CLOSE;
for (fd = 0; fd < maxfd; fd++)
close(fd);
}
if (!(flags & BD_NO_REOPEN_STD_FDS)) {
close(STDIN_FILENO);
fd = open("/dev/null", O_RDWR);
if (fd != STDIN_FILENO)
return -1;
if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO)
return -1;
if (dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO)
return -1;
}
return 0;
}
int log_data(char *date, double array_data[DATA_NUM]) {
FILE *file;
if ((file = fopen(DATALOG_FILE, "a")) == NULL)
return -1;
fprintf(file, "%s ; %.2f ; %.2f ; %.2f ; %.2f ; %.2f ; %.2f\n",
date, array_data[0], array_data[1], array_data[2],
array_data[3], array_data[4], array_data[5]);
fclose(file);
return 0;
}
这是我的问题:
当我使用 become_daemon()
函数编译我的代码并执行程序时,文件 DATALOG_FILE
(它是 "xxxxxx.txt"
的定义)没有创建。如果我在没有 become_daemon()
函数调用的情况下进行编译,则程序可以正常运行并创建文件。
我什至注意到如果我添加行
sudo /my/folder/program
在 rc.local
到 运行 中,它在启动时按我想要的方式启动,但即使在这种情况下,它也不会创建文件 DATALOG_FILE.
我是守护进程的新手所以谁能告诉我这种行为的原因吗?
正如 Ctx 在他的评论中提到的,函数 become_daemon
可能会将当前目录更改为 /
。如果 DATALOG_FILE
是相对文件名,例如您在问题中所写的 "xxxxxx.txt"
,则守护程序将无法在系统根目录中创建它,除非它具有根权限。
要么不通过将 BD_NO_CHDIR
作为参数传递给 become_daemon
来更改当前目录,要么使 DATALOG_FILE
成为绝对路径。