19 March, 2010

Do not use exit() in your C++ daemon

Do not use exit() in your C++ daemon program!!! The destructor of global variable will be invoke, it might not what you desire.

The scenario is when you try to daemonize your program, you will call exit(0) when fork()!=0. If you did that, terrible thing happens, all destructor of your global variable will be invoke. For example, the global object to do log.

To avoid this situation, use _exit() instead of exit(). The only difference between those two functions is _exit() will NOT invoke the functions register by atexit(). In the other word, the destructor will not be invoke.

Here is my C++ daemonize function:
static void daemonize()
{
if( SIG_ERR == signal(SIGTTOU, SIG_IGN) ||
SIG_ERR == signal(SIGTTIN, SIG_IGN) ||
SIG_ERR == signal(SIGTSTP, SIG_IGN) )
exit(EXIT_FAILURE);

if (0 != fork()) _exit(0);

if (-1 == setsid()) exit(EXIT_FAILURE);

umask(0);
if (0 != chdir("/")) exit(EXIT_FAILURE);

close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
}

No comments: