#include "../../../plugins/utils/UniqueProcess.hpp" #include #include #include #include #include #include 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); } }