From c16bb75c8890bbeb7d375beb110224ec0f14b115 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 10 Dec 2022 19:39:08 +0100 Subject: Matrix: re-add sync from latest cache --- src/plugins/utils/UniqueProcess.cpp | 111 ++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/plugins/utils/UniqueProcess.cpp (limited to 'src/plugins/utils') 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 +#include +#include +#include +#include +#include +#include + +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 -- cgit v1.2.3