1 /*
2 **  Become a long-running daemon.
3 **
4 **  Usage:
5 **
6 **      daemonize(path);
7 **
8 **  Performs all of the various system-specific stuff required to become a
9 **  long-running daemon.  Also chdir to the provided path (which is where
10 **  core dumps will go on most systems).
11 */
12 
13 #include "portable/system.h"
14 
15 #include <fcntl.h>
16 #include <sys/ioctl.h>
17 #include <sys/stat.h>
18 
19 #include "inn/libinn.h"
20 #include "inn/messages.h"
21 
22 void
daemonize(const char * path)23 daemonize(const char *path)
24 {
25     int status;
26     int fd;
27 
28     /* Fork and exit in the parent to disassociate from the current process
29        group and become the leader of a new process group. */
30     status = fork();
31     if (status < 0)
32         sysdie("cant fork");
33     else if (status > 0)
34         _exit(0);
35 
36         /* setsid() should take care of disassociating from the controlling
37            terminal, and FreeBSD at least doesn't like TIOCNOTTY if you don't
38            already have a controlling terminal.  So only use the older
39            TIOCNOTTY method if setsid() isn't available. */
40 #if HAVE_SETSID
41     if (setsid() < 0)
42         syswarn("cant become session leader");
43 #elif defined(TIOCNOTTY)
44     fd = open("/dev/tty", O_RDWR);
45     if (fd >= 0) {
46         if (ioctl(fd, TIOCNOTTY, NULL) < 0)
47             syswarn("cant disassociate from the terminal");
48         close(fd);
49     }
50 #endif /* defined(TIOCNOTTY) */
51 
52     if (chdir(path) < 0)
53         syswarn("cant chdir to %s", path);
54 
55     fd = open("/dev/null", O_RDWR, 0);
56     if (fd != -1) {
57         dup2(fd, STDIN_FILENO);
58         dup2(fd, STDOUT_FILENO);
59         dup2(fd, STDERR_FILENO);
60         if (fd > 2)
61             close(fd);
62     }
63 }
64