#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()); } }