Reputation: 3
I have created a program that has the option to be started as a daemon, as well as the option to redirect output to a file. Everything works as expected unless the application is started with it's output already directed to /dev/null. This is a problem because the application is being started by another application where the output is redirected to /dev/null.
Starting the application like this will work as expected, with all output written to the file.
./my_daemon -d -f/tmp/logfile
However, starting the application like this will create the log file, but it will be empty.
./my_daemon -d -f/tmp/logfile &> /dev/null
The program is:
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;
}
Upvotes: 0
Views: 1284
Reputation: 25139
After daemonizing and doing the dup2
bit and setting up stdout
and stderr
correctly, you run into this bit of code:
if (q_daemonize == TRUE)
{
if (sn_log_file >= 0)
{
close(STDOUT_FILENO);
close(STDERR_FILENO);
close(sn_log_file);
}
}
which promptly closes the file descriptors you've been so careful to attach to your log file with dup2
.
I'm presuming the purpose here is clear-up. Firstly, you can just delete this, as a process exiting will clean up its own FDs. Secondly, this is causing a problem as your printf
statement above will not have been flushed to the file descriptor for stdout
as stdio is buffered. If you fflush
stdout, it will probably work, but the better strategy is simply to exit and let stdio
's own exit handlers close the file.
Upvotes: 1