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:
parent
d4d3566421
commit
f179d1fac5
3 changed files with 40 additions and 7 deletions
|
@ -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 );
|
||||||
|
|
|
@ -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() :
|
||||||
|
|
|
@ -49,12 +49,15 @@ 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]) {
|
||||||
auto settings_node = settings[backend_settings_section];
|
try {
|
||||||
const std::string plugin_path = find_plugin_by_name(split_and_trim(search_paths, ':'), parOut.backend_name);
|
auto settings_node = settings[backend_settings_section];
|
||||||
if (plugin_path.empty())
|
const std::string plugin_path = find_plugin_by_name(split_and_trim(search_paths, ':'), parOut.backend_name);
|
||||||
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() + "\"");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue