我创建了一个程序,可以选择作为守护程序启动,以及将输出重定向到文件的选项。一切都按预期工作,除非应用程序启动它的输出已经定向到/ dev / null。这是一个问题,因为应用程序正由另一个将输出重定向到/ dev / null的应用程序启动。
像这样启动应用程序将按预期工作,并将所有输出写入文件。
./my_daemon -d -f/tmp/logfile
但是,启动这样的应用程序将创建日志文件,但它将为空。
./my_daemon -d -f/tmp/logfile &> /dev/null
该计划是:
sintn main(sintn osn_argc, charn *opacn_argv[])
{
sintn sn_i;
charn *pcn_log_file = NULL;
boolean q_daemonize;
sintn sn_log_file = -1;
pid_t t_pid = 0;
pid_t t_sid = 0;
printf("Enter Main\n");
//check for parameters
for (sn_i = 1; sn_i < osn_argc; sn_i++)
{
if (opacn_argv[sn_i][0] == '-')
{
switch(opacn_argv[sn_i][1])
{
case 'd':
case 'D':
q_daemonize = TRUE;
break;
case 'f':
case 'F':
pcn_log_file = &opacn_argv[sn_i][2];
break;
default:
printf("Unknown parameter '%s'\n", opacn_argv[sn_i]);
}
}
}
if (q_daemonize == TRUE)
{
t_pid = fork();// fork a new child process
if (t_pid < 0)
{
printf("Fork failed!\n");
exit(1);
}
if (t_pid > 0)// its the parent process
{
printf("Forked: pid of child process %d \n", t_pid);
exit(0); //terminate the parent process succesfully
}
umask(0);//unmasking the file mode
t_sid = setsid();//set new session
if(t_sid < 0)
{
exit(1);
}
close(STDIN_FILENO);
if (pcn_log_file != NULL)
{
sn_log_file = open(pcn_log_file, O_CREAT | O_APPEND | O_WRONLY, S_IRWXU | S_IRWXG | S_IRWXO );
}
if (sn_log_file >= 0)
{
dup2(sn_log_file, STDOUT_FILENO);
dup2(sn_log_file, STDERR_FILENO);
}
else
{
close(STDOUT_FILENO);
close(STDERR_FILENO);
}
}
printf("Starting Application\n");
v_BRIDGE_process();
printf("Application Exit\n");
printf("Exit Main\n");
if (q_daemonize == TRUE)
{
if (sn_log_file >= 0)
{
close(STDOUT_FILENO);
close(STDERR_FILENO);
close(sn_log_file);
}
}
return EXIT_SUCCESS;
}
答案 0 :(得分:1)
在进行守护并执行dup2
位并正确设置stdout
和stderr
之后,您会碰到这段代码:
if (q_daemonize == TRUE)
{
if (sn_log_file >= 0)
{
close(STDOUT_FILENO);
close(STDERR_FILENO);
close(sn_log_file);
}
}
会立即关闭您使用dup2
小心附加到日志文件的文件描述符。
我认为这里的目的是明确的。首先,你可以删除它,因为退出的进程将清理自己的FD。其次,这会导致问题,因为上面的printf
语句不会被刷新到stdout
的文件描述符,因为缓冲了stdio。如果你fflush
stdout,它可能会有效,但更好的策略就是退出并让stdio
自己的退出处理程序关闭文件。