diff --git a/include/utils.h b/include/utils.h index 89fa659..6632864 100644 --- a/include/utils.h +++ b/include/utils.h @@ -21,6 +21,8 @@ #define P_BYTES(bytes, start) pretty_bytes((bytes), (start), (char[16]){0}, 16) #define P_NUM(num) pretty_num((num), (char[8]){0}, 8) +int get_instance_lock(void); + void timespec_add_ms(struct timespec *ts, uint16_t ms); uint64_t timespec_diff_us(const struct timespec *a, const struct timespec *b); diff --git a/src/utils.c b/src/utils.c index 55ced08..1050494 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,15 +1,39 @@ +#include #include #include #include #include #include #include +#include #include #include #include "log.h" #include "utils.h" +int get_instance_lock(void) { + const char *xdg_runtime_dir = getenv("XDG_RUNTIME_DIR"); + char tmp_dir[256]; + snprintf(tmp_dir, sizeof(tmp_dir), "%s/linuxSmartie.lock", xdg_runtime_dir); + + const int file = open(tmp_dir, O_CREAT | O_RDWR | O_CLOEXEC, 0600); + if (file < 0) { + applog(LOG_ERR, "Couldn't create a lock file at %s", tmp_dir); + return -1; + } + + if (flock(file, LOCK_EX | LOCK_NB) < 0) { + if (errno == EWOULDBLOCK) + applog(LOG_ERR, "another instance already running, this one will exit."); + else + applog(LOG_ERR, "flock failed: %s", strerror(errno)); + close(file); + return -1; + } + return 0; +} + inline void timespec_add_ms(struct timespec *ts, const uint16_t ms) { ts->tv_nsec += ms * 1000000L; if (ts->tv_nsec >= 1000000000L) {