13 #define EXIT_SUCCESS 0
14 #define EXIT_FAILURE 1
17 static void child_handler(int signum
)
32 void daemonize(const char *lockfile
, const char *username
)
34 pid_t pid
, sid
, parent
;
37 /* already a daemon */
42 /* Create the lock file as the current user */
43 if (lockfile
&& lockfile
[0]) {
44 lfp
= open(lockfile
, O_RDWR
|O_CREAT
, 0640);
46 syslog(LOG_ERR
, "unable to create lock file %s, code=%d (%s)",
47 lockfile
, errno
, strerror(errno
));
52 /* Drop user if there is one, and we were run as root */
53 if (username
!= NULL
&& (getuid() == 0 || geteuid() == 0)) {
54 struct passwd
*pw
= getpwnam(username
);
56 syslog(LOG_NOTICE
, "setting user to %s", username
);
61 /* Trap signals that we expect to recieve */
62 signal(SIGCHLD
, child_handler
);
63 signal(SIGUSR1
, child_handler
);
64 signal(SIGALRM
, child_handler
);
66 /* Fork off the parent process */
69 syslog(LOG_ERR
, "unable to fork daemon, code=%d (%s)",
70 errno
, strerror(errno
));
73 /* If we got a good PID, then we can exit the parent process. */
76 /* Wait for confirmation from the child via SIGTERM or SIGCHLD, or
77 for two seconds to elapse (SIGALRM). pause() should not return. */
84 /* At this point we are executing as the child process */
87 /* Cancel certain signals */
88 signal(SIGCHLD
, SIG_DFL
); /* A child process dies */
89 signal(SIGTSTP
, SIG_IGN
); /* Various TTY signals */
90 signal(SIGTTOU
, SIG_IGN
);
91 signal(SIGTTIN
, SIG_IGN
);
92 signal(SIGHUP
, SIG_IGN
); /* Ignore hangup signal */
93 signal(SIGTERM
, SIG_DFL
); /* Die on SIGTERM */
95 /* Change the file mode mask */
98 /* Create a new SID for the child process */
101 syslog(LOG_ERR
, "unable to create a new session, code %d (%s)",
102 errno
, strerror(errno
));
106 /* Change the current working directory. This prevents the current
107 directory from being locked; hence not being able to remove it. */
108 if ((chdir("/")) < 0) {
109 syslog(LOG_ERR
, "unable to change directory to %s, code %d (%s)",
110 "/", errno
, strerror(errno
));
114 /* Redirect standard files to /dev/null */
115 freopen("/dev/null", "r", stdin
);
116 freopen("/dev/null", "w", stdout
);
117 freopen("/dev/null", "w", stderr
);
119 /* Tell the parent process that we are A-okay */
120 kill(parent
, SIGUSR1
);