1
0
Fork 0
mirror of https://github.com/KingDuckZ/dindexer.git synced 2024-11-25 00:53:43 +00:00

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.
This commit is contained in:
King_DuckZ 2017-08-23 20:52:49 +01:00
parent d4d3566421
commit f179d1fac5
3 changed files with 40 additions and 7 deletions

View file

@ -21,6 +21,7 @@
#include <string> #include <string>
#include <memory> #include <memory>
#include <boost/utility/string_ref.hpp> #include <boost/utility/string_ref.hpp>
#include <exception>
namespace YAML { namespace YAML {
class Node; class Node;
@ -31,6 +32,11 @@ namespace dindb {
using BackendPtr = std::unique_ptr<dindb::Backend, void(*)(dindb::Backend*)>; using BackendPtr = std::unique_ptr<dindb::Backend, void(*)(dindb::Backend*)>;
class SOLoadException : public std::runtime_error {
public:
explicit SOLoadException (std::string&& parMessage);
};
class BackendPlugin { class BackendPlugin {
public: public:
BackendPlugin ( void ); BackendPlugin ( void );

View file

@ -21,6 +21,9 @@
#include "backends/backend_loader.hpp" #include "backends/backend_loader.hpp"
#include "backends/exposed_functions.hpp" #include "backends/exposed_functions.hpp"
#include "backends/backend_version.hpp" #include "backends/backend_version.hpp"
#include "dindexer-machinery/scantask/mime.hpp"
#include "dindexer-machinery/scantask/singlefile.hpp"
#include "dindexer-machinery/recorddata.hpp"
#include <dlfcn.h> #include <dlfcn.h>
#include <cassert> #include <cassert>
#include <functional> #include <functional>
@ -72,17 +75,38 @@ namespace dindb {
auto get_version = reinterpret_cast<GetVersionFun>(dlsym(parSOHandle, "dindexer_backend_iface_version")); auto get_version = reinterpret_cast<GetVersionFun>(dlsym(parSOHandle, "dindexer_backend_iface_version"));
return get_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<SingleFileTask> file(new SingleFileTask(parPath));
Mime mime(file, true);
const std::vector<mchlib::FileRecordData>& 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 } //unnamed namespace
SOLoadException::SOLoadException (std::string&& parMessage) :
std::runtime_error(std::move(parMessage))
{
}
std::string backend_name (const std::string& parSOPath) { std::string backend_name (const std::string& parSOPath) {
assert(not parSOPath.empty()); assert(not parSOPath.empty());
using SoHandle = std::unique_ptr<void, int(*)(void*)>; using SoHandle = std::unique_ptr<void, int(*)(void*)>;
if (get_mime_type(parSOPath) != "application/x-sharedlib")
return std::string();
auto handle = SoHandle(dlopen(parSOPath.c_str(), RTLD_LAZY), &dlclose); auto handle = SoHandle(dlopen(parSOPath.c_str(), RTLD_LAZY), &dlclose);
if (handle) if (handle)
return backend_name(handle.get()); return backend_name(handle.get());
else else
return std::string(); throw SOLoadException(dlerror());
} }
BackendPlugin::BackendPlugin() : BackendPlugin::BackendPlugin() :

View file

@ -49,13 +49,16 @@ namespace dinlib {
parOut.backend_name = settings["backend_name"].as<std::string>(); parOut.backend_name = settings["backend_name"].as<std::string>();
const std::string backend_settings_section = parOut.backend_name + "_settings"; const std::string backend_settings_section = parOut.backend_name + "_settings";
if (settings[backend_settings_section]) { if (settings[backend_settings_section]) {
try {
auto settings_node = 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); 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); parOut.backend_plugin = dindb::BackendPlugin(plugin_path, &settings_node);
throw_if_plugin_failed(parOut.backend_plugin, plugin_path, parOut.backend_name); 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() + "\"");
}
}
} }
namespace { namespace {