# HG changeset patch # User David Demelier # Date 1530898374 -7200 # Node ID bd7feaa002cb6c999216c7b912119fe36fbfe250 # Parent 4b5dba257d81bb60ac49f70b921d28765f5a4be2 Irccd: check ABI compatibility in dynlib_plugin diff -r 4b5dba257d81 -r bd7feaa002cb cmake/IrccdVersion.cmake --- 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. diff -r 4b5dba257d81 -r bd7feaa002cb cmake/internal/sysconfig.hpp.in --- 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@" /* diff -r 4b5dba257d81 -r bd7feaa002cb libirccd/irccd/daemon/dynlib_plugin.cpp --- 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 { 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 wrap(boost::shared_ptr ptr) noexcept -{ - return std::shared_ptr(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 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 { - return wrap(boost::dll::import(path, symbol(path))); + const auto [ abisym, initsym ] = symbol(path); + + using abisym_func_type = unsigned (); + using initsym_func_type = std::unique_ptr (); + + const auto abi = boost::dll::import(path, abisym); + const auto init = boost::dll::import(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(plg.release(), [init] (auto ptr) mutable { + delete ptr; + }); } } // !irccd diff -r 4b5dba257d81 -r bd7feaa002cb libirccd/irccd/daemon/dynlib_plugin.hpp --- 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 open(const std::string& id, - const std::string& file) noexcept override; + auto open(const std::string& id, + const std::string& file) -> std::shared_ptr override; }; } // !irccd diff -r 4b5dba257d81 -r bd7feaa002cb plugins/links/links.cpp --- 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 +{ + return std::make_unique("links", ""); +} + +} // !C } // !irccd