aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/daemonise.c57
-rw-r--r--src/daemonise.h18
-rw-r--r--src/satd.c13
3 files changed, 81 insertions, 7 deletions
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;
}