From 68587e2920b52ad75f0badb4d3040b574797ac9e Mon Sep 17 00:00:00 2001 From: Phil Jones Date: Tue, 25 Oct 2022 00:26:03 +0100 Subject: Disallow multiple simultaneous tofi instances. --- src/lock.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/lock.c (limited to 'src/lock.c') diff --git a/src/lock.c b/src/lock.c new file mode 100644 index 0000000..133d327 --- /dev/null +++ b/src/lock.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include +#include "log.h" +#include "xmalloc.h" + +static const char *default_cache_dir = ".cache/"; +static const char *lock_filename = "tofi.lock"; + +[[nodiscard("memory leaked")]] +static char *get_lock_path() { + char *lock_name = NULL; + const char *runtime_path = getenv("XDG_RUNTIME_DIR"); + if (runtime_path == NULL) { + runtime_path = getenv("XDG_CACHE_HOME"); + } + if (runtime_path == NULL) { + const char *home = getenv("HOME"); + if (home == NULL) { + log_error("Couldn't retrieve HOME from environment.\n"); + return NULL; + } + size_t len = strlen(home) + 1 + + strlen(default_cache_dir) + 1 + + strlen(lock_filename) + 1; + lock_name = xmalloc(len); + snprintf( + lock_name, + len, + "%s/%s/%s", + home, + default_cache_dir, + lock_filename); + } else { + size_t len = strlen(runtime_path) + 1 + + strlen(lock_filename) + 1; + lock_name = xmalloc(len); + snprintf( + lock_name, + len, + "%s/%s", + runtime_path, + lock_filename); + } + return lock_name; +} + +bool lock_check(void) +{ + bool ret = false; + char *filename = get_lock_path(); + errno = 0; + int fd = open(filename, O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR); + if (fd == -1) { + log_error("Failed to open lock file %s: %s.\n", filename, strerror(errno)); + } else if (flock(fd, LOCK_EX | LOCK_NB) == -1) { + if (errno == EWOULDBLOCK) { + /* + * We can't lock the file because another tofi process + * already has. + */ + ret = true; + } + } + + free(filename); + return ret; +} -- cgit v1.2.3