From f179d1fac5027af2136c024388b6730935c848b5 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Wed, 23 Aug 2017 20:52:49 +0100 Subject: [PATCH] Give more details when plugin discovery fails for a legit reason. Skip files the whose mime type is not application/x-sharedlib, which would be the ones allowed to fail loading. All errors on failed dlopen() attempts now cause the code to throw. --- include/backends/backend_loader.hpp | 6 ++++++ src/backends/backend_loader.cpp | 26 +++++++++++++++++++++++++- src/common/settings.cpp | 15 +++++++++------ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/include/backends/backend_loader.hpp b/include/backends/backend_loader.hpp index 7795d0c..fa9f594 100644 --- a/include/backends/backend_loader.hpp +++ b/include/backends/backend_loader.hpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace YAML { class Node; @@ -31,6 +32,11 @@ namespace dindb { using BackendPtr = std::unique_ptr; + class SOLoadException : public std::runtime_error { + public: + explicit SOLoadException (std::string&& parMessage); + }; + class BackendPlugin { public: BackendPlugin ( void ); diff --git a/src/backends/backend_loader.cpp b/src/backends/backend_loader.cpp index 05b5909..0b217ec 100644 --- a/src/backends/backend_loader.cpp +++ b/src/backends/backend_loader.cpp @@ -21,6 +21,9 @@ #include "backends/backend_loader.hpp" #include "backends/exposed_functions.hpp" #include "backends/backend_version.hpp" +#include "dindexer-machinery/scantask/mime.hpp" +#include "dindexer-machinery/scantask/singlefile.hpp" +#include "dindexer-machinery/recorddata.hpp" #include #include #include @@ -72,17 +75,38 @@ namespace dindb { auto get_version = reinterpret_cast(dlsym(parSOHandle, "dindexer_backend_iface_version")); return get_version(); } + + std::string get_mime_type (const std::string& parPath) { + using mchlib::scantask::SingleFileTask; + using mchlib::scantask::Mime; + using std::shared_ptr; + + shared_ptr file(new SingleFileTask(parPath)); + Mime mime(file, true); + + const std::vector& result = mime.get_or_create(); + assert(result.size() == 1); + boost::string_ref retval = result.front().mime_type(); + return std::string(retval.data(), retval.size()); + } } //unnamed namespace + SOLoadException::SOLoadException (std::string&& parMessage) : + std::runtime_error(std::move(parMessage)) + { + } + std::string backend_name (const std::string& parSOPath) { assert(not parSOPath.empty()); using SoHandle = std::unique_ptr; + if (get_mime_type(parSOPath) != "application/x-sharedlib") + return std::string(); auto handle = SoHandle(dlopen(parSOPath.c_str(), RTLD_LAZY), &dlclose); if (handle) return backend_name(handle.get()); else - return std::string(); + throw SOLoadException(dlerror()); } BackendPlugin::BackendPlugin() : diff --git a/src/common/settings.cpp b/src/common/settings.cpp index bdb66d2..cebcbc4 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -49,12 +49,15 @@ namespace dinlib { parOut.backend_name = settings["backend_name"].as(); const std::string backend_settings_section = parOut.backend_name + "_settings"; if (settings[backend_settings_section]) { - auto settings_node = settings[backend_settings_section]; - const std::string plugin_path = find_plugin_by_name(split_and_trim(search_paths, ':'), parOut.backend_name); - if (plugin_path.empty()) - throw std::runtime_error(std::string("Unable to find any suitable plugin with the specified name \"") + parOut.backend_name + "\""); - parOut.backend_plugin = dindb::BackendPlugin(plugin_path, &settings_node); - throw_if_plugin_failed(parOut.backend_plugin, plugin_path, parOut.backend_name); + try { + auto settings_node = settings[backend_settings_section]; + const std::string plugin_path = find_plugin_by_name(split_and_trim(search_paths, ':'), parOut.backend_name); + parOut.backend_plugin = dindb::BackendPlugin(plugin_path, &settings_node); + throw_if_plugin_failed(parOut.backend_plugin, plugin_path, parOut.backend_name); + } + catch (const dindb::SOLoadException& err) { + throw std::runtime_error(std::string("Unable to find any suitable plugin with the specified name \"") + err.what() + "\""); + } } }