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