From d7dd2d885c3dc8711c04f564b06169bc1ccefe1d Mon Sep 17 00:00:00 2001
From: Mattias Andrée <maandree@member.fsf.org>
Date: Fri, 25 Dec 2015 17:15:03 +0100
Subject: daemonise
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Mattias Andrée <maandree@member.fsf.org>
---
 src/daemonise.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 src/daemonise.h | 18 ++++++++++++++++++
 src/satd.c      | 13 ++++++++++++-
 3 files changed, 81 insertions(+), 7 deletions(-)

(limited to 'src')

diff --git a/src/daemonise.c b/src/daemonise.c
index d98e134..929eca0 100644
--- a/src/daemonise.c
+++ b/src/daemonise.c
@@ -19,12 +19,13 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  * 
- * This file is copied from <http:/github.com/maandree/slibc>.
+ * This file is copied from <http://github.com/maandree/slibc>.
  */
 #include <unistd.h>
 #include <fcntl.h>
 #include <signal.h>
 #include <string.h>
+#include <stdlib.h>
 #include <errno.h>
 #include <sys/resource.h>
 
@@ -35,6 +36,11 @@
  */
 extern char** environ;
 
+/**
+ * The pidfile created by `daemonise`.
+ */
+static char* __pidfile = NULL;
+
 
 
 /**
@@ -100,6 +106,8 @@ extern char** environ;
  * should be used instead of /run for the runtime data-files
  * directory, in which the PID file is stored.
  * 
+ * This is a slibc extension.
+ * 
  * @etymology  (Daemonise) the process!
  * 
  * @param   name   The name of the daemon. Use a hardcoded value,
@@ -225,18 +233,26 @@ int daemonise(const char* name, int flags)
   run = getenv("XDG_RUNTIME_DIR");
   if (run && *run)
     {
-      pidpath = alloca(sizeof("/.pid") + (strlen(run) + strlen(name)) * sizeof(char));
+      pidpath = malloc(sizeof("/.pid") + (strlen(run) + strlen(name)) * sizeof(char));
+      t (pidfile == NULL);
       stpcpy(stpcpy(stpcpy(stpcpy(pidpath, run), "/"), name), ".pid");
     }
   else
     {
-      pidpath = alloca(sizeof("/run/.pid") + strlen(name) * sizeof(char));
+      pidpath = malloc(sizeof("/run/.pid") + strlen(name) * sizeof(char));
+      t (pidfile == NULL);
       stpcpy(stpcpy(stpcpy(pidpath, "/run/"), name), ".pid");
     }
   fd = open(pidpath, O_WRONLY | O_CREAT | O_EXCL, 0644);
-  t (fd == -1);
+  if (fd == -1)
+    {
+      saved_errno = errno;
+      free(pidpath), pidpath = NULL;
+      errno = saved_errno;
+      goto fail;
+    }
   pid = getpid();
-  t (dprintf(fd, "%lli\n", (long long int)pid) < 0);
+  t (dprintf(fd, "%lli\n", (long long int)pid)) < 0;
   t (close(fd) && (errno != EINTR));
  no_pid_file:
   
@@ -264,12 +280,13 @@ int daemonise(const char* name, int flags)
     {
       if (flags & DAEMONISE_KEEP_STDERR)
 	return -1;
+      undaemonise();
       abort(); /* Do not overcomplicate things, just abort in this unlikely event. */
     }
   
   return 0;
  fail:
-  saved_errno = err;
+  saved_errno = errno;
   if (pipe_rw[0] >= 0)  close(pipe_rw[0]);
   if (pipe_rw[1] >= 0)  close(pipe_rw[1]);
   if (fd         >= 0)  close(fd);
@@ -277,3 +294,31 @@ int daemonise(const char* name, int flags)
   return -1;
 }
 
+
+/**
+ * Remove the PID file created by `daemonise`. This shall
+ * always be called before exiting after calling `daemonise`,
+ * even if it failed.
+ * 
+ * This is a slibc extension.
+ * 
+ * @etymology  (Un)link PID file created by `(daemonise)`!
+ * 
+ * @return  Zero on success, -1 on error.
+ * 
+ * @throws  Any error specified for unlink(3).
+ * 
+ * @since  Always.
+ */
+int undaemonise(void)
+{
+  int r, saved_errno;
+  if (pidfile == NULL)
+    return 0;
+  r = unlink(pidfile);
+  saved_errno = errno;
+  free(pidfile), pidfile = NULL;
+  errno = saved_errno;
+  return r;
+}
+
diff --git a/src/daemonise.h b/src/daemonise.h
index 72a2fda..33c0aec 100644
--- a/src/daemonise.h
+++ b/src/daemonise.h
@@ -179,3 +179,21 @@
  */
 int daemonise(const char* name, int flags);
 
+
+/**
+ * Remove the PID file created by `daemonise`. This shall
+ * always be called before exiting after calling `daemonise`,
+ * even if it failed.
+ * 
+ * This is a slibc extension.
+ * 
+ * @etymology  (Un)link PID file created by `(daemonise)`!
+ * 
+ * @return  Zero on success, -1 on error.
+ * 
+ * @throws  Any error specified for unlink(3).
+ * 
+ * @since  Always.
+ */
+int undaemonise(void);
+
diff --git a/src/satd.c b/src/satd.c
index 4534ae4..db9cc4b 100644
--- a/src/satd.c
+++ b/src/satd.c
@@ -23,6 +23,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "daemonise.h"
+
 
 
 /**
@@ -59,6 +61,15 @@ main(int argc, char *argv[])
 		foreground = 1;
 	}
 
-	/* TODO guess what, this is going to be the daemon */
+	if (foreground ? 0 : daemonise(0))
+		goto fail;
+
+	undaemonise();
+	return 0;
+
+fail:
+	perror(argv0);
+	undaemonise();
+	return 1;
 }
 
-- 
cgit v1.2.3-70-g09d2