/*
- * Copyright (C) 1997-2010 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 1997-2010 Andre Noll <maan@tuebingen.mpg.de>
*
* Licensed under the GPL v2. For licencing details see COPYING.
*/
#include <stdio.h>
#include "gcc-compat.h"
-#include "error.h"
+#include "err.h"
#include "log.h"
-#include "string.h"
+#include "str.h"
#include "daemon.h"
/**
*
* \sa fork(2), setsid(2), dup(2).
*/
-void daemon_init(void)
+int daemon_init(void)
{
pid_t pid;
- int null;
+ int null, fd[2];
DSS_INFO_LOG(("daemonizing\n"));
+ if (pipe(fd) < 0)
+ goto err;
pid = fork();
if (pid < 0)
goto err;
- if (pid)
- exit(EXIT_SUCCESS); /* parent exits */
+ if (pid) {
+ /*
+ * The parent process exits once it has received one byte from
+ * the reading end of the pipe. If the child exits before it
+ * was able to complete its setup (acquire the lock on the
+ * semaphore), the read() below will return zero. In this case
+ * we let the parent die unsuccessfully.
+ */
+ char c;
+ int ret;
+ close(fd[1]);
+ ret = read(fd[0], &c, 1);
+ if (ret <= 0) {
+ DSS_EMERG_LOG(("child terminated unexpectedly\n"));
+ exit(EXIT_FAILURE);
+ }
+ exit(EXIT_SUCCESS);
+ }
+ close(fd[0]);
/* become session leader */
if (setsid() < 0)
goto err;
- if (chdir("/") < 0)
- goto err;
umask(0);
- null = open("/dev/null", O_RDONLY);
+ null = open("/dev/null", O_RDWR);
if (null < 0)
goto err;
if (dup2(null, STDIN_FILENO) < 0)
if (dup2(null, STDERR_FILENO) < 0)
goto err;
close(null);
- return;
+ return fd[1];
err:
DSS_EMERG_LOG(("fatal: %s\n", strerror(errno)));
exit(EXIT_FAILURE);