aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/utils')
-rw-r--r--src/plugins/utils/UniqueProcess.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/plugins/utils/UniqueProcess.cpp b/src/plugins/utils/UniqueProcess.cpp
new file mode 100644
index 0000000..76b9cb1
--- /dev/null
+++ b/src/plugins/utils/UniqueProcess.cpp
@@ -0,0 +1,113 @@
+#include "../../../plugins/utils/UniqueProcess.hpp"
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+namespace QuickMedia {
+ static bool is_process_running_program(pid_t pid, const char *program_name) {
+ char filepath[256];
+ snprintf(filepath, sizeof(filepath), "/proc/%ld/cmdline", (long)pid);
+
+ int fd = open(filepath, O_RDONLY);
+ if(fd == -1)
+ return false;
+
+ char buffer[PATH_MAX + 1];
+ ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
+ if(bytes_read == -1) {
+ close(fd);
+ return false;
+ }
+ buffer[bytes_read] = '\0';
+
+ char resolved_path[PATH_MAX + 1];
+ if(!realpath(buffer, resolved_path)) {
+ close(fd);
+ return false;
+ }
+ bytes_read = strlen(resolved_path);
+ resolved_path[bytes_read] = '\0';
+
+ const char *end = resolved_path + bytes_read;
+ const char *start = (const char*)memrchr(resolved_path, '/', bytes_read);
+ if(start)
+ start += 1;
+ else
+ start = buffer;
+
+ const size_t cmd_arg0_len = end - start;
+ const size_t program_name_len = strlen(program_name);
+ bool running = (cmd_arg0_len == program_name_len && memcmp(start, program_name, program_name_len) == 0);
+ close(fd);
+ return running;
+ }
+
+ bool is_quickmedia_instance_already_running(const char *pid_file_dir, const char *plugin_name) {
+ char pid_file[PATH_MAX];
+ snprintf(pid_file, sizeof(pid_file), "%s/quickmedia.%s.pid", pid_file_dir, plugin_name);
+
+ char buffer[256];
+ int fd = open(pid_file, O_RDONLY);
+ if(fd == -1)
+ return false;
+
+ ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
+ if(bytes_read < 0) {
+ perror("failed to read quickmedia pid file");
+ close(fd);
+ return false;
+ }
+ buffer[bytes_read] = '\0';
+ close(fd);
+
+ bool running = false;
+ long pid = 0;
+ if(sscanf(buffer, "%ld", &pid) == 1) {
+ if(is_process_running_program(pid, "quickmedia")) {
+ fprintf(stderr, "Error: quickmedia %s is already running\n", plugin_name);
+ running = true;
+ }
+ } else {
+ fprintf(stderr, "Warning: quickmedia pid file is in incorrect format, it's possible that its corrupt. Replacing file and continuing...\n");
+ running = false;
+ }
+
+ if(!running)
+ unlink(pid_file);
+
+ return running;
+ }
+
+ bool set_quickmedia_instance_unique(const char *pid_file_dir, const char *plugin_name) {
+ char pid_file[PATH_MAX];
+ snprintf(pid_file, sizeof(pid_file), "%s/quickmedia.%s.pid", pid_file_dir, plugin_name);
+
+ int fd = open(pid_file, O_WRONLY|O_CREAT|O_TRUNC, 0777);
+ if(fd == -1) {
+ perror("failed to create quickmedia pid file");
+ return false;
+ }
+
+ bool success = true;
+ char buffer[256];
+ const int buffer_size = snprintf(buffer, sizeof(buffer), "%ld", (long)getpid());
+ if(write(fd, buffer, buffer_size) == -1) {
+ perror("failed to write quickmedia pid file");
+ success = false;
+ }
+
+ close(fd);
+ if(!success)
+ unlink(pid_file);
+ return success;
+ }
+
+ void remove_quickmedia_instance_lock(const char *pid_file_dir, const char *plugin_name) {
+ char pid_file[PATH_MAX];
+ snprintf(pid_file, sizeof(pid_file), "%s/quickmedia.%s.pid", pid_file_dir, plugin_name);
+ unlink(pid_file);
+ }
+} \ No newline at end of file