summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEamon Walsh <ewalsh@tycho.nsa.gov>2011-07-01 16:42:27 -0400
committerEamon Walsh <ewalsh@tycho.nsa.gov>2011-07-01 16:42:27 -0400
commit177f54fee936b891d52999a4b509295d86b5d6e2 (patch)
tree0961aa2858ddc76ef911876596ac01496d03b72f
parent0b716a87000f86e4537611336ac96f54466759bd (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.
-rw-r--r--src/monitor.c38
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);