#include <sys/stat.h>
#include <fcntl.h>
/* Bit-mask values for 'flags' argument of becomeDaemon() */ #define BD_NO_CHDIR 01 /* Don't chdir("/") */
#define BD_NO_CLOSE_FILES 02 /* Don't close all open files */
#define BD_NO_REOPEN_STD_FDS 04 /* Don't reopen stdin, stdout, and
stderr to /dev/null */
#define BD_NO_UMASK0 010 /* Don't do a umask(0) */ #define BD_MAX_CLOSE 8192 /* Maximum file descriptors to close if
sysconf(_SC_OPEN_MAX) is indeterminate */
int becomeDaemon(int flags) /* Returns 0 on success, -1 on error */ {
int maxfd, fd; switch (fork()) /* Become background process */
{
case -: return -;
case : break; /* Child falls through... */
default: _exit(EXIT_SUCCESS); /* while parent terminates */
} if (setsid() == -) /* Become leader of new session */
return -; switch (fork()) { /* Ensure we are not session leader */
case -: return -;
case : break;
default: _exit(EXIT_SUCCESS);
} if (!(flags & BD_NO_UMASK0))
umask(); /* Clear file mode creation mask */ if (!(flags & BD_NO_CHDIR))
chdir("/"); /* Change to root directory */ if (!(flags & BD_NO_CLOSE_FILES)) { /* Close all open files */
maxfd = sysconf(_SC_OPEN_MAX);
if (maxfd == -) /* Limit is indeterminate... */
maxfd = BD_MAX_CLOSE; /* so take a guess */ for (fd = ; fd < maxfd; fd++)
close(fd);
} if (!(flags & BD_NO_REOPEN_STD_FDS)) {
close(STDIN_FILENO); /* Reopen standard fd's to /dev/null */ fd = open("/dev/null", O_RDWR); if (fd != STDIN_FILENO) /* 'fd' should be 0 */
return -;
if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO)
return -;
if (dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO)
return -;
} return ;
}