Select Git revision
PluginsLoader.cpp
-
Stéphane Del Pino authored
Plugins are loaded through environment variables. Two environment variables are read: PUGS_PLUGIN and PUGS_PLUGIN_DIR - PUGS_PLUGIN is a string literal that contains the filename of the dynamic library that contains plugins. One can provide multiple filename using semicolumn separators. ex. PUGS_PLUGIN="/path/to/my/libplugin1.so;/anotherpath/to/another/libplugin2.so" - PUGS_PLUGIN_DIR is a string literal that contains directory path where plugins (dynamic libraries) are. One can provide multiple path using semicolumn separators. All the dynamic libraries present at the locations are loaded! ex. PUGS_PLUGIN="/path/to/a/plugin/list/;/anotherpath/to/another/plugin/list/"
Stéphane Del Pino authoredPlugins are loaded through environment variables. Two environment variables are read: PUGS_PLUGIN and PUGS_PLUGIN_DIR - PUGS_PLUGIN is a string literal that contains the filename of the dynamic library that contains plugins. One can provide multiple filename using semicolumn separators. ex. PUGS_PLUGIN="/path/to/my/libplugin1.so;/anotherpath/to/another/libplugin2.so" - PUGS_PLUGIN_DIR is a string literal that contains directory path where plugins (dynamic libraries) are. One can provide multiple path using semicolumn separators. All the dynamic libraries present at the locations are loaded! ex. PUGS_PLUGIN="/path/to/a/plugin/list/;/anotherpath/to/another/plugin/list/"
PluginsLoader.cpp 2.69 KiB
#include <utils/PluginsLoader.hpp>
#include <dlfcn.h>
#include <rang.hpp>
#include <filesystem>
#include <iostream>
#include <sstream>
#include <unistd.h>
#include <vector>
std::vector<std::string>
split(const std::string& full_string)
{
std::vector<std::string> split_string;
std::stringstream is(full_string);
std::string segment;
while (std::getline(is, segment, ';')) {
if (segment.size() > 0) {
split_string.push_back(segment);
}
}
return split_string;
}
void
PluginsLoader::_open(const std::string& plugin)
{
auto handle = dlopen(plugin.c_str(), RTLD_NOW);
if (handle != nullptr) {
m_dl_handler_stack.push(handle);
std::cout << " * \"" << rang::fgB::green << plugin << rang::fg::reset << "\"\n";
} else {
std::cout << " " << rang::fgB::red << "cannot load " << rang::fg::reset << '\"' << rang::fgB::yellow << plugin
<< rang::fg::reset << "\"\n";
}
}
PluginsLoader::PluginsLoader()
{
std::vector<std::string> plugin_vector;
{
char* env = getenv("PUGS_PLUGIN");
if (env != nullptr) {
std::string plugins = env;
plugin_vector = split(plugins);
}
}
{
char* env = getenv("PUGS_PLUGIN_DIR");
if (env != nullptr) {
std::string paths = env;
std::vector<std::string> path_vector = split(paths);
for (auto&& path : path_vector) {
if (access(path.c_str(), R_OK) == -1) {
std::cout << ' ' << rang::fgB::red << 'X' << rang::fg::reset << " cannot access plugin dir \""
<< rang::fgB::yellow << path << rang::fg::reset << "\"\n";
} else {
for (auto&& entry :
std::filesystem::directory_iterator(path,
(std::filesystem::directory_options::follow_directory_symlink |
std::filesystem::directory_options::skip_permission_denied))) {
if (entry.path().extension() == ".so") {
plugin_vector.push_back(entry.path().string());
}
}
}
}
}
}
// keep unique entries
std::sort(plugin_vector.begin(), plugin_vector.end());
plugin_vector.resize(std::distance(plugin_vector.begin(), std::unique(plugin_vector.begin(), plugin_vector.end())));
if (plugin_vector.size() > 0) {
std::cout << rang::style::bold << "Loading plugins" << rang::style::reset << '\n';
for (auto&& plugin : plugin_vector) {
this->_open(plugin);
}
std::cout << "-------------------------------------------------------\n";
}
}
PluginsLoader::~PluginsLoader()
{
while (not m_dl_handler_stack.empty()) {
dlclose(m_dl_handler_stack.top());
m_dl_handler_stack.pop();
}
}