From 995f5b53eaea97f08f7de433f4e51bb0d5610019 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Fri, 25 Dec 2015 16:54:39 +0100 Subject: add undaemonise MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- include/unistd.h | 19 ++++++++++++++++++ src/unistd/daemonise.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/include/unistd.h b/include/unistd.h index 4629e8e..963bb96 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -1138,6 +1138,8 @@ int daemon(int, int) * 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, @@ -1174,6 +1176,23 @@ int daemon(int, int) */ int daemonise(const char*, int) __GCC_ONLY(__attribute__((__nonnull__, __warn_unused_result__))); + +/** + * 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); #endif diff --git a/src/unistd/daemonise.c b/src/unistd/daemonise.c index a8fe3ab..f3ebe3a 100644 --- a/src/unistd/daemonise.c +++ b/src/unistd/daemonise.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,11 @@ */ extern char** environ; +/** + * The pidfile created by `daemonise`. + */ +static char* __pidfile = NULL; + /** @@ -96,6 +102,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, @@ -221,16 +229,24 @@ 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 (close(fd) && (errno != EINTR)); @@ -260,12 +276,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); @@ -273,3 +290,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; +} + -- cgit v1.2.3-70-g09d2