Mercurial > irccd
changeset 706:bd7feaa002cb
Irccd: check ABI compatibility in dynlib_plugin
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 06 Jul 2018 19:32:54 +0200 |
parents | 4b5dba257d81 |
children | 48afa8c41f50 |
files | cmake/IrccdVersion.cmake cmake/internal/sysconfig.hpp.in libirccd/irccd/daemon/dynlib_plugin.cpp libirccd/irccd/daemon/dynlib_plugin.hpp plugins/links/links.cpp |
diffstat | 5 files changed, 48 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/cmake/IrccdVersion.cmake Fri Jul 06 22:10:10 2018 +0200 +++ b/cmake/IrccdVersion.cmake Fri Jul 06 19:32:54 2018 +0200 @@ -32,7 +32,7 @@ set(IRCCD_VERSION_MINOR "0") set(IRCCD_VERSION_PATCH "0") set(IRCCD_VERSION "${IRCCD_VERSION_MAJOR}.${IRCCD_VERSION_MINOR}.${IRCCD_VERSION_PATCH}-dev${HG_REV}") -set(IRCCD_VERSION_SHLIB "3") +set(IRCCD_VERSION_SHLIB "1") # # Irccd release date.
--- a/cmake/internal/sysconfig.hpp.in Fri Jul 06 22:10:10 2018 +0200 +++ b/cmake/internal/sysconfig.hpp.in Fri Jul 06 19:32:54 2018 +0200 @@ -44,6 +44,7 @@ #define IRCCD_VERSION_MAJOR @IRCCD_VERSION_MAJOR@ #define IRCCD_VERSION_MINOR @IRCCD_VERSION_MINOR@ #define IRCCD_VERSION_PATCH @IRCCD_VERSION_PATCH@ +#define IRCCD_VERSION_SHLIB @IRCCD_VERSION_SHLIB@ #define IRCCD_VERSION "@IRCCD_VERSION@" /*
--- a/libirccd/irccd/daemon/dynlib_plugin.cpp Fri Jul 06 22:10:10 2018 +0200 +++ b/libirccd/irccd/daemon/dynlib_plugin.cpp Fri Jul 06 19:32:54 2018 +0200 @@ -38,7 +38,7 @@ namespace { -std::string symbol(const std::string& path) noexcept +auto symbol(const std::string& path) -> std::pair<std::string, std::string> { auto id = boost::filesystem::path(path).stem().string(); @@ -52,12 +52,10 @@ return c == '-' ? '_' : c; }); - return string_util::sprintf("irccd_plugin_%s", id); -} - -std::shared_ptr<plugin> wrap(boost::shared_ptr<plugin> ptr) noexcept -{ - return std::shared_ptr<plugin>(ptr.get(), [ptr] (auto) mutable { ptr.reset(); }); + return { + string_util::sprintf("irccd_abi_%s", id), + string_util::sprintf("irccd_init_%s", id) + }; } } // !namespace @@ -67,10 +65,32 @@ { } -std::shared_ptr<plugin> dynlib_plugin_loader::open(const std::string&, - const std::string& path) noexcept +auto dynlib_plugin_loader::open(const std::string& id, + const std::string& path) -> std::shared_ptr<plugin> { - return wrap(boost::dll::import<plugin>(path, symbol(path))); + const auto [ abisym, initsym ] = symbol(path); + + using abisym_func_type = unsigned (); + using initsym_func_type = std::unique_ptr<plugin> (); + + const auto abi = boost::dll::import<abisym_func_type>(path, abisym); + const auto init = boost::dll::import<initsym_func_type>(path, initsym); + + if (abi() != IRCCD_VERSION_SHLIB) + throw plugin_error(plugin_error::exec_error, id, "incompatible version"); + + auto plg = init(); + + if (!plg) + throw plugin_error(plugin_error::exec_error, id, "invalid plugin"); + + /* + * We need to keep a reference to `init' variable for the whole plugin + * lifetime. + */ + return std::shared_ptr<plugin>(plg.release(), [init] (auto ptr) mutable { + delete ptr; + }); } } // !irccd
--- a/libirccd/irccd/daemon/dynlib_plugin.hpp Fri Jul 06 22:10:10 2018 +0200 +++ b/libirccd/irccd/daemon/dynlib_plugin.hpp Fri Jul 06 19:32:54 2018 +0200 @@ -43,8 +43,8 @@ /** * \copydoc plugin_loader::open */ - std::shared_ptr<plugin> open(const std::string& id, - const std::string& file) noexcept override; + auto open(const std::string& id, + const std::string& file) -> std::shared_ptr<plugin> override; }; } // !irccd
--- a/plugins/links/links.cpp Fri Jul 06 22:10:10 2018 +0200 +++ b/plugins/links/links.cpp Fri Jul 06 19:32:54 2018 +0200 @@ -424,8 +424,20 @@ } // !namespace -extern "C" BOOST_SYMBOL_EXPORT links_plugin irccd_plugin_links; +extern "C" { + +BOOST_SYMBOL_EXPORT +auto irccd_abi_links() -> unsigned +{ + return IRCCD_VERSION_SHLIB; +} -links_plugin irccd_plugin_links("links", ""); +BOOST_SYMBOL_EXPORT +auto irccd_init_links() -> std::unique_ptr<plugin> +{ + return std::make_unique<links_plugin>("links", ""); +} + +} // !C } // !irccd