summaryrefslogtreecommitdiffstats
path: root/support/nfs/mydaemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'support/nfs/mydaemon.c')
-rw-r--r--support/nfs/mydaemon.c92
1 files changed, 47 insertions, 45 deletions
diff --git a/support/nfs/mydaemon.c b/support/nfs/mydaemon.c
index e885d60..3391eff 100644
--- a/support/nfs/mydaemon.c
+++ b/support/nfs/mydaemon.c
@@ -46,56 +46,61 @@
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <xlog.h>
+#include "nfslib.h"
+
+static int pipefds[2] = { -1, -1};
+
/**
- * mydaemon - daemonize, but have parent wait to exit
- * @nochdir: skip chdir()'ing the child to / after forking if true
- * @noclose: skip closing stdin/stdout/stderr if true
- * @pipefds: pointer to 2 element array of pipefds
+ * daemon_init - initial daemon setup
+ * @fg: whether to run in the foreground
*
* This function is like daemon(), but with our own special sauce to delay
* the exit of the parent until the child is set up properly. A pipe is created
* between parent and child. The parent process will wait to exit until the
- * child dies or writes a '1' on the pipe signaling that it started
- * successfully.
+ * child dies or writes an int on the pipe signaling its status.
*/
void
-mydaemon(int nochdir, int noclose, int *pipefds)
+daemon_init(bool fg)
{
int pid, status, tempfd;
+ if (fg)
+ return;
+
if (pipe(pipefds) < 0) {
xlog_err("mydaemon: pipe() failed: errno %d (%s)\n",
errno, strerror(errno));
- exit(1);
+ exit(EXIT_FAILURE);
}
- if ((pid = fork ()) < 0) {
+
+ pid = fork();
+ if (pid < 0) {
xlog_err("mydaemon: fork() failed: errno %d (%s)\n",
errno, strerror(errno));
- exit(1);
+ exit(EXIT_FAILURE);
}
- if (pid != 0) {
- /*
- * Parent. Wait for status from child.
- */
+ if (pid > 0) {
+ /* Parent */
close(pipefds[1]);
- if (read(pipefds[0], &status, 1) != 1)
- exit(1);
- exit (0);
+ if (read(pipefds[0], &status, sizeof(status)) != sizeof(status))
+ exit(EXIT_FAILURE);
+ exit(status);
}
- /* Child. */
+
+ /* Child */
close(pipefds[0]);
setsid ();
- if (nochdir == 0) {
- if (chdir ("/") == -1) {
- xlog_err("mydaemon: chdir() failed: errno %d (%s)\n",
- errno, strerror(errno));
- exit(1);
- }
+
+ if (chdir ("/")) {
+ xlog_err("mydaemon: chdir() failed: errno %d (%s)\n",
+ errno, strerror(errno));
+ exit(EXIT_FAILURE);
}
while (pipefds[1] <= 2) {
@@ -103,41 +108,38 @@ mydaemon(int nochdir, int noclose, int *pipefds)
if (pipefds[1] < 0) {
xlog_err("mydaemon: dup() failed: errno %d (%s)\n",
errno, strerror(errno));
- exit(1);
+ exit(EXIT_FAILURE);
}
}
- if (noclose == 0) {
- tempfd = open("/dev/null", O_RDWR);
- if (tempfd >= 0) {
- dup2(tempfd, 0);
- dup2(tempfd, 1);
- dup2(tempfd, 2);
- close(tempfd);
- } else {
- xlog_err("mydaemon: can't open /dev/null: errno %d "
- "(%s)\n", errno, strerror(errno));
- exit(1);
- }
+ tempfd = open("/dev/null", O_RDWR);
+ if (tempfd < 0) {
+ xlog_err("mydaemon: can't open /dev/null: errno %d "
+ "(%s)\n", errno, strerror(errno));
+ exit(EXIT_FAILURE);
}
- return;
+ dup2(tempfd, 0);
+ dup2(tempfd, 1);
+ dup2(tempfd, 2);
+ dup2(pipefds[1], 3);
+ pipefds[1] = 3;
+ closeall(4);
}
/**
- * release_parent - tell the parent that it can exit now
- * @pipefds: pipefd array that was previously passed to mydaemon()
+ * daemon_ready - tell interested parties that the daemon is ready
*
- * This function tells the parent process of mydaemon() that it's now clear
- * to exit(0).
+ * This function tells e.g. the parent process that the daemon is up
+ * and running.
*/
void
-release_parent(int *pipefds)
+daemon_ready(void)
{
- int status;
+ int status = 0;
if (pipefds[1] > 0) {
- if (write(pipefds[1], &status, 1) != 1) {
+ if (write(pipefds[1], &status, sizeof(status)) != sizeof(status)) {
xlog_err("WARN: writing to parent pipe failed: errno "
"%d (%s)\n", errno, strerror(errno));
}