在已经重定向到 /dev/null 时重定向守护程序输出
redirecting daemon output when already redirected to /dev/null
我创建了一个程序,它可以选择作为守护进程启动,也可以选择将输出重定向到文件。一切都按预期工作,除非应用程序启动时它的输出已经定向到 /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;
}
在守护进程和执行 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
自己的退出处理程序关闭文件。
我创建了一个程序,它可以选择作为守护进程启动,也可以选择将输出重定向到文件。一切都按预期工作,除非应用程序启动时它的输出已经定向到 /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;
}
在守护进程和执行 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
自己的退出处理程序关闭文件。