diff options
author | dec05eba <dec05eba@protonmail.com> | 2022-12-10 19:39:08 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2022-12-10 19:39:08 +0100 |
commit | c16bb75c8890bbeb7d375beb110224ec0f14b115 (patch) | |
tree | 6d10897048c83758baeb524a5b7ca9169f894900 /src/plugins/utils | |
parent | 2f8e3dedd4c33e5759adea186c1f1bb77c242069 (diff) |
Matrix: re-add sync from latest cache
Diffstat (limited to 'src/plugins/utils')
-rw-r--r-- | src/plugins/utils/UniqueProcess.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/plugins/utils/UniqueProcess.cpp b/src/plugins/utils/UniqueProcess.cpp new file mode 100644 index 0000000..d2025f5 --- /dev/null +++ b/src/plugins/utils/UniqueProcess.cpp @@ -0,0 +1,111 @@ +#include "../../../plugins/utils/UniqueProcess.hpp" +#include "../../../include/Storage.hpp" +#include <stdio.h> +#include <limits.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +namespace QuickMedia { + bool is_quickmedia_instance_already_running(const char *sock_file_dir, const char *plugin_name) { + char sock_file[PATH_MAX]; + snprintf(sock_file, sizeof(sock_file), "%s/quickmedia.%s.sock", sock_file_dir, plugin_name); + + std::string resolved_path; + if(file_get_content(sock_file, resolved_path) != 0) + return false; + + resolved_path.resize(108); // sizeof(addr.sun_path) is 108 + + int fd = socket(AF_UNIX, SOCK_STREAM, 0); + if(fd == -1) { + fprintf(stderr, "Error: failed to create unix domain socket, error: %s\n", strerror(errno)); + return true; + } + + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); + + struct sockaddr_un addr; + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, resolved_path.c_str()); + + bool running = connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0; + int err = errno; + if(err == EAGAIN) + running = true; + else if(err == ENOENT) + running = false; + close(fd); + return running; + } + + bool set_quickmedia_instance_unique(const char *sock_file_dir, const char *plugin_name) { + char socket_file[] = "/tmp/quickmedia.XXXXXX"; + int tmp_file_fd = mkstemp(socket_file); + if(tmp_file_fd == -1) { + fprintf(stderr, "Error: failed to create temporary file for unix domain socket, error: %s\n", strerror(errno)); + return false; + } + unlink(socket_file); + close(tmp_file_fd); + + int fd = socket(AF_UNIX, SOCK_STREAM, 0); + if(fd == -1) { + fprintf(stderr, "Error: failed to create unix domain socket, error: %s\n", strerror(errno)); + return false; + } + + struct sockaddr_un addr; + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, socket_file); + + if(bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { + fprintf(stderr, "Error: failed to bind unix domain socket, error: %s\n", strerror(errno)); + unlink(socket_file); + close(fd); + return false; + } + + if(listen(fd, 0) == -1) { + fprintf(stderr, "Error: failed to listen to unix domain socket, error: %s\n", strerror(errno)); + unlink(socket_file); + close(fd); + return false; + } + + char sock_file[PATH_MAX]; + snprintf(sock_file, sizeof(sock_file), "%s/quickmedia.%s.sock", sock_file_dir, plugin_name); + bool success = file_overwrite(sock_file, socket_file) == 0; + if(!success) { + fprintf(stderr, "Error: failed to create %s unix domain socket link file\n", sock_file); + unlink(socket_file); + close(fd); + } + return success; + } + + void remove_quickmedia_instance_lock(const char *sock_file_dir, const char *plugin_name) { + char sock_file[PATH_MAX]; + snprintf(sock_file, sizeof(sock_file), "%s/quickmedia.%s.sock", sock_file_dir, plugin_name); + + std::string resolved_path; + if(file_get_content(sock_file, resolved_path) != 0) { + unlink(sock_file); + return; + } + + resolved_path.resize(108); // sizeof(addr.sun_path) is 108 + + if(resolved_path.size() < 4 || memcmp(resolved_path.data(), "/tmp", 4) != 0) { + unlink(sock_file); + return; + } + + unlink(sock_file); + unlink(resolved_path.c_str()); + } +}
\ No newline at end of file |