1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker * This code is mainly taken from Doug Potter's page
3*1c60b9acSAndroid Build Coastguard Worker *
4*1c60b9acSAndroid Build Coastguard Worker * http://www-theorie.physik.unizh.ch/~dpotter/howto/daemonize
5*1c60b9acSAndroid Build Coastguard Worker *
6*1c60b9acSAndroid Build Coastguard Worker * I contacted him 2007-04-16 about the license for the original code,
7*1c60b9acSAndroid Build Coastguard Worker * he replied it is Public Domain. Use the URL above to get the original
8*1c60b9acSAndroid Build Coastguard Worker * Public Domain version if you want it.
9*1c60b9acSAndroid Build Coastguard Worker *
10*1c60b9acSAndroid Build Coastguard Worker * This version is MIT like the rest of libwebsockets and is
11*1c60b9acSAndroid Build Coastguard Worker * Copyright (c)2006 - 2013 Andy Green <[email protected]>
12*1c60b9acSAndroid Build Coastguard Worker *
13*1c60b9acSAndroid Build Coastguard Worker *
14*1c60b9acSAndroid Build Coastguard Worker * You're much better advised to use systemd to daemonize stuff without needing
15*1c60b9acSAndroid Build Coastguard Worker * this kind of support in the app itself.
16*1c60b9acSAndroid Build Coastguard Worker */
17*1c60b9acSAndroid Build Coastguard Worker
18*1c60b9acSAndroid Build Coastguard Worker #include <stdlib.h>
19*1c60b9acSAndroid Build Coastguard Worker #include <string.h>
20*1c60b9acSAndroid Build Coastguard Worker #include <stdio.h>
21*1c60b9acSAndroid Build Coastguard Worker #include <signal.h>
22*1c60b9acSAndroid Build Coastguard Worker #include <sys/types.h>
23*1c60b9acSAndroid Build Coastguard Worker #include <sys/stat.h>
24*1c60b9acSAndroid Build Coastguard Worker #include <fcntl.h>
25*1c60b9acSAndroid Build Coastguard Worker #include <limits.h>
26*1c60b9acSAndroid Build Coastguard Worker #include <unistd.h>
27*1c60b9acSAndroid Build Coastguard Worker #include <errno.h>
28*1c60b9acSAndroid Build Coastguard Worker
29*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets.h>
30*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
31*1c60b9acSAndroid Build Coastguard Worker
32*1c60b9acSAndroid Build Coastguard Worker pid_t pid_daemon;
33*1c60b9acSAndroid Build Coastguard Worker static char *lock_path;
34*1c60b9acSAndroid Build Coastguard Worker
get_daemonize_pid()35*1c60b9acSAndroid Build Coastguard Worker pid_t get_daemonize_pid()
36*1c60b9acSAndroid Build Coastguard Worker {
37*1c60b9acSAndroid Build Coastguard Worker return pid_daemon;
38*1c60b9acSAndroid Build Coastguard Worker }
39*1c60b9acSAndroid Build Coastguard Worker
40*1c60b9acSAndroid Build Coastguard Worker static void
child_handler(int signum)41*1c60b9acSAndroid Build Coastguard Worker child_handler(int signum)
42*1c60b9acSAndroid Build Coastguard Worker {
43*1c60b9acSAndroid Build Coastguard Worker int len, sent, fd;
44*1c60b9acSAndroid Build Coastguard Worker char sz[20];
45*1c60b9acSAndroid Build Coastguard Worker
46*1c60b9acSAndroid Build Coastguard Worker switch (signum) {
47*1c60b9acSAndroid Build Coastguard Worker
48*1c60b9acSAndroid Build Coastguard Worker case SIGALRM: /* timed out daemonizing */
49*1c60b9acSAndroid Build Coastguard Worker exit(0);
50*1c60b9acSAndroid Build Coastguard Worker break;
51*1c60b9acSAndroid Build Coastguard Worker
52*1c60b9acSAndroid Build Coastguard Worker case SIGUSR1: /* positive confirmation we daemonized well */
53*1c60b9acSAndroid Build Coastguard Worker
54*1c60b9acSAndroid Build Coastguard Worker if (!lock_path)
55*1c60b9acSAndroid Build Coastguard Worker exit(0);
56*1c60b9acSAndroid Build Coastguard Worker
57*1c60b9acSAndroid Build Coastguard Worker /* Create the lock file as the current user */
58*1c60b9acSAndroid Build Coastguard Worker
59*1c60b9acSAndroid Build Coastguard Worker fd = lws_open(lock_path, O_TRUNC | O_RDWR | O_CREAT, 0640);
60*1c60b9acSAndroid Build Coastguard Worker if (fd < 0) {
61*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr,
62*1c60b9acSAndroid Build Coastguard Worker "unable to create lock file %s, code=%d (%s)\n",
63*1c60b9acSAndroid Build Coastguard Worker lock_path, errno, strerror(errno));
64*1c60b9acSAndroid Build Coastguard Worker exit(0);
65*1c60b9acSAndroid Build Coastguard Worker }
66*1c60b9acSAndroid Build Coastguard Worker len = sprintf(sz, "%u", (unsigned int)pid_daemon);
67*1c60b9acSAndroid Build Coastguard Worker sent = (int)write(fd, sz, (size_t)len);
68*1c60b9acSAndroid Build Coastguard Worker if (sent != len)
69*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr,
70*1c60b9acSAndroid Build Coastguard Worker "unable to write pid to lock file %s, code=%d (%s)\n",
71*1c60b9acSAndroid Build Coastguard Worker lock_path, errno, strerror(errno));
72*1c60b9acSAndroid Build Coastguard Worker
73*1c60b9acSAndroid Build Coastguard Worker close(fd);
74*1c60b9acSAndroid Build Coastguard Worker
75*1c60b9acSAndroid Build Coastguard Worker exit(0);
76*1c60b9acSAndroid Build Coastguard Worker //!!(sent == len));
77*1c60b9acSAndroid Build Coastguard Worker
78*1c60b9acSAndroid Build Coastguard Worker case SIGCHLD: /* daemonization failed */
79*1c60b9acSAndroid Build Coastguard Worker exit(0);
80*1c60b9acSAndroid Build Coastguard Worker break;
81*1c60b9acSAndroid Build Coastguard Worker }
82*1c60b9acSAndroid Build Coastguard Worker }
83*1c60b9acSAndroid Build Coastguard Worker
lws_daemon_closing(int sigact)84*1c60b9acSAndroid Build Coastguard Worker static void lws_daemon_closing(int sigact)
85*1c60b9acSAndroid Build Coastguard Worker {
86*1c60b9acSAndroid Build Coastguard Worker if (getpid() == pid_daemon)
87*1c60b9acSAndroid Build Coastguard Worker if (lock_path) {
88*1c60b9acSAndroid Build Coastguard Worker unlink(lock_path);
89*1c60b9acSAndroid Build Coastguard Worker lws_free_set_NULL(lock_path);
90*1c60b9acSAndroid Build Coastguard Worker }
91*1c60b9acSAndroid Build Coastguard Worker
92*1c60b9acSAndroid Build Coastguard Worker kill(getpid(), SIGKILL);
93*1c60b9acSAndroid Build Coastguard Worker }
94*1c60b9acSAndroid Build Coastguard Worker
95*1c60b9acSAndroid Build Coastguard Worker /*
96*1c60b9acSAndroid Build Coastguard Worker * You just need to call this from your main(), when it
97*1c60b9acSAndroid Build Coastguard Worker * returns you are all set "in the background" decoupled
98*1c60b9acSAndroid Build Coastguard Worker * from the console you were started from.
99*1c60b9acSAndroid Build Coastguard Worker *
100*1c60b9acSAndroid Build Coastguard Worker * The process context you called from has been terminated then.
101*1c60b9acSAndroid Build Coastguard Worker */
102*1c60b9acSAndroid Build Coastguard Worker
103*1c60b9acSAndroid Build Coastguard Worker int
lws_daemonize(const char * _lock_path)104*1c60b9acSAndroid Build Coastguard Worker lws_daemonize(const char *_lock_path)
105*1c60b9acSAndroid Build Coastguard Worker {
106*1c60b9acSAndroid Build Coastguard Worker struct sigaction act;
107*1c60b9acSAndroid Build Coastguard Worker pid_t sid, parent;
108*1c60b9acSAndroid Build Coastguard Worker
109*1c60b9acSAndroid Build Coastguard Worker /* already a daemon */
110*1c60b9acSAndroid Build Coastguard Worker // if (getppid() == 1)
111*1c60b9acSAndroid Build Coastguard Worker // return 1;
112*1c60b9acSAndroid Build Coastguard Worker
113*1c60b9acSAndroid Build Coastguard Worker if (_lock_path) {
114*1c60b9acSAndroid Build Coastguard Worker int n;
115*1c60b9acSAndroid Build Coastguard Worker
116*1c60b9acSAndroid Build Coastguard Worker int fd = lws_open(_lock_path, O_RDONLY);
117*1c60b9acSAndroid Build Coastguard Worker if (fd >= 0) {
118*1c60b9acSAndroid Build Coastguard Worker char buf[10];
119*1c60b9acSAndroid Build Coastguard Worker
120*1c60b9acSAndroid Build Coastguard Worker n = (int)read(fd, buf, sizeof(buf));
121*1c60b9acSAndroid Build Coastguard Worker close(fd);
122*1c60b9acSAndroid Build Coastguard Worker if (n) {
123*1c60b9acSAndroid Build Coastguard Worker int ret;
124*1c60b9acSAndroid Build Coastguard Worker n = atoi(buf);
125*1c60b9acSAndroid Build Coastguard Worker ret = kill(n, 0);
126*1c60b9acSAndroid Build Coastguard Worker if (ret >= 0) {
127*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr,
128*1c60b9acSAndroid Build Coastguard Worker "Daemon already running pid %d\n",
129*1c60b9acSAndroid Build Coastguard Worker n);
130*1c60b9acSAndroid Build Coastguard Worker exit(1);
131*1c60b9acSAndroid Build Coastguard Worker }
132*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr,
133*1c60b9acSAndroid Build Coastguard Worker "Removing stale lock %s from dead pid %d\n",
134*1c60b9acSAndroid Build Coastguard Worker _lock_path, n);
135*1c60b9acSAndroid Build Coastguard Worker unlink(lock_path);
136*1c60b9acSAndroid Build Coastguard Worker }
137*1c60b9acSAndroid Build Coastguard Worker }
138*1c60b9acSAndroid Build Coastguard Worker
139*1c60b9acSAndroid Build Coastguard Worker n = (int)strlen(_lock_path) + 1;
140*1c60b9acSAndroid Build Coastguard Worker lock_path = lws_malloc((unsigned int)n, "daemonize lock");
141*1c60b9acSAndroid Build Coastguard Worker if (!lock_path) {
142*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr, "Out of mem in lws_daemonize\n");
143*1c60b9acSAndroid Build Coastguard Worker return 1;
144*1c60b9acSAndroid Build Coastguard Worker }
145*1c60b9acSAndroid Build Coastguard Worker strcpy(lock_path, _lock_path);
146*1c60b9acSAndroid Build Coastguard Worker }
147*1c60b9acSAndroid Build Coastguard Worker
148*1c60b9acSAndroid Build Coastguard Worker /* Trap signals that we expect to receive */
149*1c60b9acSAndroid Build Coastguard Worker signal(SIGCHLD, child_handler); /* died */
150*1c60b9acSAndroid Build Coastguard Worker signal(SIGUSR1, child_handler); /* was happy */
151*1c60b9acSAndroid Build Coastguard Worker signal(SIGALRM, child_handler); /* timeout daemonizing */
152*1c60b9acSAndroid Build Coastguard Worker
153*1c60b9acSAndroid Build Coastguard Worker /* Fork off the parent process */
154*1c60b9acSAndroid Build Coastguard Worker pid_daemon = fork();
155*1c60b9acSAndroid Build Coastguard Worker if ((int)pid_daemon < 0) {
156*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr, "unable to fork daemon, code=%d (%s)",
157*1c60b9acSAndroid Build Coastguard Worker errno, strerror(errno));
158*1c60b9acSAndroid Build Coastguard Worker exit(9);
159*1c60b9acSAndroid Build Coastguard Worker }
160*1c60b9acSAndroid Build Coastguard Worker
161*1c60b9acSAndroid Build Coastguard Worker /* If we got a good PID, then we can exit the parent process. */
162*1c60b9acSAndroid Build Coastguard Worker if (pid_daemon > 0) {
163*1c60b9acSAndroid Build Coastguard Worker
164*1c60b9acSAndroid Build Coastguard Worker /*
165*1c60b9acSAndroid Build Coastguard Worker * Wait for confirmation signal from the child via
166*1c60b9acSAndroid Build Coastguard Worker * SIGCHILD / USR1, or for two seconds to elapse
167*1c60b9acSAndroid Build Coastguard Worker * (SIGALRM). pause() should not return.
168*1c60b9acSAndroid Build Coastguard Worker */
169*1c60b9acSAndroid Build Coastguard Worker alarm(2);
170*1c60b9acSAndroid Build Coastguard Worker
171*1c60b9acSAndroid Build Coastguard Worker pause();
172*1c60b9acSAndroid Build Coastguard Worker /* should not be reachable */
173*1c60b9acSAndroid Build Coastguard Worker exit(1);
174*1c60b9acSAndroid Build Coastguard Worker }
175*1c60b9acSAndroid Build Coastguard Worker
176*1c60b9acSAndroid Build Coastguard Worker /* At this point we are executing as the child process */
177*1c60b9acSAndroid Build Coastguard Worker parent = getppid();
178*1c60b9acSAndroid Build Coastguard Worker pid_daemon = getpid();
179*1c60b9acSAndroid Build Coastguard Worker
180*1c60b9acSAndroid Build Coastguard Worker /* Cancel certain signals */
181*1c60b9acSAndroid Build Coastguard Worker signal(SIGCHLD, SIG_DFL); /* A child process dies */
182*1c60b9acSAndroid Build Coastguard Worker signal(SIGTSTP, SIG_IGN); /* Various TTY signals */
183*1c60b9acSAndroid Build Coastguard Worker signal(SIGTTOU, SIG_IGN);
184*1c60b9acSAndroid Build Coastguard Worker signal(SIGTTIN, SIG_IGN);
185*1c60b9acSAndroid Build Coastguard Worker signal(SIGHUP, SIG_IGN); /* Ignore hangup signal */
186*1c60b9acSAndroid Build Coastguard Worker
187*1c60b9acSAndroid Build Coastguard Worker /* Change the file mode mask */
188*1c60b9acSAndroid Build Coastguard Worker umask(0);
189*1c60b9acSAndroid Build Coastguard Worker
190*1c60b9acSAndroid Build Coastguard Worker /* Create a new SID for the child process */
191*1c60b9acSAndroid Build Coastguard Worker sid = setsid();
192*1c60b9acSAndroid Build Coastguard Worker if (sid < 0) {
193*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr,
194*1c60b9acSAndroid Build Coastguard Worker "unable to create a new session, code %d (%s)",
195*1c60b9acSAndroid Build Coastguard Worker errno, strerror(errno));
196*1c60b9acSAndroid Build Coastguard Worker exit(2);
197*1c60b9acSAndroid Build Coastguard Worker }
198*1c60b9acSAndroid Build Coastguard Worker
199*1c60b9acSAndroid Build Coastguard Worker /*
200*1c60b9acSAndroid Build Coastguard Worker * Change the current working directory. This prevents the current
201*1c60b9acSAndroid Build Coastguard Worker * directory from being locked; hence not being able to remove it.
202*1c60b9acSAndroid Build Coastguard Worker */
203*1c60b9acSAndroid Build Coastguard Worker if (chdir("/tmp") < 0) {
204*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr,
205*1c60b9acSAndroid Build Coastguard Worker "unable to change directory to %s, code %d (%s)",
206*1c60b9acSAndroid Build Coastguard Worker "/", errno, strerror(errno));
207*1c60b9acSAndroid Build Coastguard Worker exit(3);
208*1c60b9acSAndroid Build Coastguard Worker }
209*1c60b9acSAndroid Build Coastguard Worker
210*1c60b9acSAndroid Build Coastguard Worker /* Redirect standard files to /dev/null */
211*1c60b9acSAndroid Build Coastguard Worker if (!freopen("/dev/null", "r", stdin))
212*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr, "unable to freopen() stdin, code %d (%s)",
213*1c60b9acSAndroid Build Coastguard Worker errno, strerror(errno));
214*1c60b9acSAndroid Build Coastguard Worker
215*1c60b9acSAndroid Build Coastguard Worker if (!freopen("/dev/null", "w", stdout))
216*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr, "unable to freopen() stdout, code %d (%s)",
217*1c60b9acSAndroid Build Coastguard Worker errno, strerror(errno));
218*1c60b9acSAndroid Build Coastguard Worker
219*1c60b9acSAndroid Build Coastguard Worker if (!freopen("/dev/null", "w", stderr))
220*1c60b9acSAndroid Build Coastguard Worker fprintf(stderr, "unable to freopen() stderr, code %d (%s)",
221*1c60b9acSAndroid Build Coastguard Worker errno, strerror(errno));
222*1c60b9acSAndroid Build Coastguard Worker
223*1c60b9acSAndroid Build Coastguard Worker /* Tell the parent process that we are A-okay */
224*1c60b9acSAndroid Build Coastguard Worker kill(parent, SIGUSR1);
225*1c60b9acSAndroid Build Coastguard Worker
226*1c60b9acSAndroid Build Coastguard Worker act.sa_handler = lws_daemon_closing;
227*1c60b9acSAndroid Build Coastguard Worker sigemptyset(&act.sa_mask);
228*1c60b9acSAndroid Build Coastguard Worker act.sa_flags = 0;
229*1c60b9acSAndroid Build Coastguard Worker
230*1c60b9acSAndroid Build Coastguard Worker sigaction(SIGTERM, &act, NULL);
231*1c60b9acSAndroid Build Coastguard Worker
232*1c60b9acSAndroid Build Coastguard Worker /* return to continue what is now "the daemon" */
233*1c60b9acSAndroid Build Coastguard Worker
234*1c60b9acSAndroid Build Coastguard Worker return 0;
235*1c60b9acSAndroid Build Coastguard Worker }
236*1c60b9acSAndroid Build Coastguard Worker
237