diff options
author | Josh Blum <josh@joshknows.com> | 2010-03-21 16:53:50 -0700 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2010-03-21 16:53:50 -0700 |
commit | d66efda608db9f6a1c2ab64659556b53810d87b7 (patch) | |
tree | edee79716e8a29cb3f21ebb148d2a6f6bbed347a /host/lib/load_modules.cpp | |
parent | d1ecc555e53770f1a5608000352f56f48c36c310 (diff) | |
download | uhd-d66efda608db9f6a1c2ab64659556b53810d87b7.tar.gz uhd-d66efda608db9f6a1c2ab64659556b53810d87b7.tar.bz2 uhd-d66efda608db9f6a1c2ab64659556b53810d87b7.zip |
Added ability to load modules at runtime
(specified by environment variable path).
Added a demo test module as well.
Diffstat (limited to 'host/lib/load_modules.cpp')
-rw-r--r-- | host/lib/load_modules.cpp | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/host/lib/load_modules.cpp b/host/lib/load_modules.cpp new file mode 100644 index 000000000..700afcd3f --- /dev/null +++ b/host/lib/load_modules.cpp @@ -0,0 +1,117 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <uhd/utils.hpp> +#include <boost/format.hpp> +#include <boost/foreach.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/filesystem.hpp> +#include <iostream> +#include <stdexcept> +#include <cstdlib> + +namespace fs = boost::filesystem; + +/*********************************************************************** + * Module Load Function + **********************************************************************/ +#ifdef HAVE_DLFCN_H +#include <dlfcn.h> + +static void load_module(const std::string &file_name){ + if (dlopen(file_name.c_str(), RTLD_LAZY) == NULL){ + throw std::runtime_error(str( + boost::format("dlopen failed to load \"%s\"") % file_name + )); + } +} + +#elif HAVE_WINBASE_H +#include <Winbase.h> + +static void load_module(const std::string &file_name){ + if (LoadLibrary(file_name.c_str()) == NULL){ + throw std::runtime_error(str( + boost::format("LoadLibrary failed to load \"%s\"") % file_name + )); + } +} + +#else + +static void load_module(const std::string &file_name){ + throw std::runtime_error(str( + boost::format("Module loading not supported: Cannot load \"%s\"") % file_name + )); +} + +#endif + +/*********************************************************************** + * Load Modules + **********************************************************************/ +/*! + * Load all modules in a given path. + * This will recurse into sub-directories. + * Does not throw, prints to std error. + * \param path the filesystem path + */ +static void load_path(const fs::path &path){ + if (not fs::exists(path)){ + std::cerr << boost::format("Module path \"%s\" not found.") % path.file_string() << std::endl; + return; + } + + //try to load the files in this path + if (fs::is_directory(path)){ + for( + fs::directory_iterator dir_itr(path); + dir_itr != fs::directory_iterator(); + ++dir_itr + ){ + load_path(dir_itr->path()); + } + return; + } + + //its not a directory, try to load it + try{ + load_module(path.file_string()); + } + catch(const std::exception &err){ + std::cerr << boost::format("Error: %s") % err.what() << std::endl; + } +} + +/*! + * Load all the modules given by the module path enviroment variable. + * The path variable may be several paths split by path separators. + */ +STATIC_BLOCK(load_modules){ + //get the environment variable module path + char *env_module_path = std::getenv("UHD_MODULE_PATH"); + if (env_module_path == NULL) return; + + //split the path at the path separators + std::vector<std::string> module_paths; + boost::split(module_paths, env_module_path, boost::is_any_of(":;")); + + //load modules in each path + BOOST_FOREACH(const std::string &module_path, module_paths){ + load_path(fs::system_complete(fs::path(module_path))); + } +} |