diff options
author | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2011-07-01 16:42:27 -0400 |
---|---|---|
committer | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2011-07-01 16:42:27 -0400 |
commit | 177f54fee936b891d52999a4b509295d86b5d6e2 (patch) | |
tree | 0961aa2858ddc76ef911876596ac01496d03b72f /src | |
parent | 0b716a87000f86e4537611336ac96f54466759bd (diff) |
Redo the daemonizing code in the monitor program.
We can't fork() after the setup code because of threads created by
libraries. But we need to wait until after the setup code to exit
the parent process, because systemd considers the daemon ready to
service clients when this happens. Thus, daemon() can't be used and
a manual solution is needed.
Diffstat (limited to 'src')
-rw-r--r-- | src/monitor.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/src/monitor.c b/src/monitor.c index 1df3f2e..a7ddbe1 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -37,17 +37,47 @@ static int timetodie; * Is called in case of process signals. */ static void -server_sighandler(int sig) +monitor_sighandler(int sig) { timetodie = 1; } +static int +monitor_fork(void) +{ + int pipefd[2]; + pid_t pid; + char tmp; + + if (chdir("/") < 0) + exit(1); + if (pipe(pipefd) < 0) + exit(1); + + pid = fork(); + + if (pid < 0) + exit(5); + if (pid > 0) { + close(pipefd[1]); + while (read(pipefd[0], &tmp, 1) != 0); + exit(0); + } + + close(pipefd[0]); + return pipefd[1]; +} + /* * Main */ int main (int argc, char *argv[]) { - struct sigaction sa = { .sa_handler = server_sighandler }; + struct sigaction sa = { .sa_handler = monitor_sighandler }; + int writefd; + + /* Fork and wait in the parent */ + writefd = monitor_fork(); /* Set up sighandlers */ sigaction(SIGINT, &sa, NULL); @@ -63,8 +93,8 @@ int main (int argc, char *argv[]) if (xenfb_monitor_init() < 0) return 2; - /* Create a daemon */ - daemon(0, 1); + /* Signal the parent process to exit */ + close(writefd); /* Enter select loop */ while (!timetodie && fd_run_select() == 0); |