portable directory traversal
parent
5253cb594c
commit
a49d5bf648
|
@ -20,6 +20,9 @@
|
||||||
#define __PLUGIN_H
|
#define __PLUGIN_H
|
||||||
|
|
||||||
#include <mitsuba/mitsuba.h>
|
#include <mitsuba/mitsuba.h>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
@ -36,7 +39,7 @@ class MTS_EXPORT_CORE Plugin {
|
||||||
typedef char *(*GetDescriptionFunc)();
|
typedef char *(*GetDescriptionFunc)();
|
||||||
public:
|
public:
|
||||||
/// Load a plugin from the supplied path
|
/// Load a plugin from the supplied path
|
||||||
Plugin(const std::string &shortName, const std::string &path);
|
Plugin(const std::string &shortName, const fs::path &path);
|
||||||
|
|
||||||
/// Virtual destructor
|
/// Virtual destructor
|
||||||
virtual ~Plugin();
|
virtual ~Plugin();
|
||||||
|
@ -54,7 +57,7 @@ public:
|
||||||
std::string getDescription() const;
|
std::string getDescription() const;
|
||||||
|
|
||||||
/// Return the path of this plugin
|
/// Return the path of this plugin
|
||||||
inline const std::string &getPath() const { return m_path; }
|
inline const fs::path &getPath() const { return m_path; }
|
||||||
|
|
||||||
/// Return a short name of this plugin
|
/// Return a short name of this plugin
|
||||||
inline const std::string &getShortName() const { return m_shortName; }
|
inline const std::string &getShortName() const { return m_shortName; }
|
||||||
|
@ -68,7 +71,7 @@ private:
|
||||||
void *m_handle;
|
void *m_handle;
|
||||||
#endif
|
#endif
|
||||||
std::string m_shortName;
|
std::string m_shortName;
|
||||||
std::string m_path;
|
fs::path m_path;
|
||||||
bool m_isUtility;
|
bool m_isUtility;
|
||||||
GetDescriptionFunc m_getDescription;
|
GetDescriptionFunc m_getDescription;
|
||||||
CreateInstanceFunc m_createInstance;
|
CreateInstanceFunc m_createInstance;
|
||||||
|
|
|
@ -33,19 +33,19 @@ MTS_NAMESPACE_BEGIN
|
||||||
// Abstract plugin module implementation
|
// Abstract plugin module implementation
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
Plugin::Plugin(const std::string &shortName, const std::string &path)
|
Plugin::Plugin(const std::string &shortName, const fs::path &path)
|
||||||
: m_shortName(shortName), m_path(path) {
|
: m_shortName(shortName), m_path(path) {
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
m_handle = LoadLibrary(path.c_str());
|
m_handle = LoadLibrary(path.file_string().c_str());
|
||||||
if (!m_handle) {
|
if (!m_handle) {
|
||||||
SLog(EError, "Error while loading plugin \"%s\": %s", m_path.c_str(),
|
SLog(EError, "Error while loading plugin \"%s\": %s",
|
||||||
lastErrorText().c_str());
|
m_path.file_string().c_str(), lastErrorText().c_str());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
m_handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
m_handle = dlopen(path.file_string().c_str(), RTLD_LAZY | RTLD_LOCAL);
|
||||||
if (!m_handle) {
|
if (!m_handle) {
|
||||||
SLog(EError, "Error while loading plugin \"%s\": %s", m_path.c_str(),
|
SLog(EError, "Error while loading plugin \"%s\": %s",
|
||||||
dlerror());
|
m_path.file_string().c_str(), dlerror());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
try {
|
try {
|
||||||
|
@ -80,13 +80,13 @@ void *Plugin::getSymbol(const std::string &sym) {
|
||||||
void *data = GetProcAddress(m_handle, sym.c_str());
|
void *data = GetProcAddress(m_handle, sym.c_str());
|
||||||
if (!data) {
|
if (!data) {
|
||||||
SLog(EError, "Could not resolve symbol \"%s\" in \"%s\": %s",
|
SLog(EError, "Could not resolve symbol \"%s\" in \"%s\": %s",
|
||||||
sym.c_str(), m_path.c_str(), lastErrorText().c_str());
|
sym.c_str(), m_path.file_string().c_str(), lastErrorText().c_str());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void *data = dlsym(m_handle, sym.c_str());
|
void *data = dlsym(m_handle, sym.c_str());
|
||||||
if (!data) {
|
if (!data) {
|
||||||
SLog(EError, "Could not resolve symbol \"%s\" in \"%s\": %s",
|
SLog(EError, "Could not resolve symbol \"%s\" in \"%s\": %s",
|
||||||
sym.c_str(), m_path.c_str(), dlerror());
|
sym.c_str(), m_path.file_string().c_str(), dlerror());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return data;
|
return data;
|
||||||
|
|
|
@ -31,12 +31,6 @@
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#if !defined(WIN32)
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
|
@ -79,36 +73,34 @@ void help() {
|
||||||
std::set<std::string> seen;
|
std::set<std::string> seen;
|
||||||
|
|
||||||
for (size_t i=0; i<dirPaths.size(); ++i) {
|
for (size_t i=0; i<dirPaths.size(); ++i) {
|
||||||
std::string dirPath = fs::complete(dirPaths[i]).file_string();
|
fs::path dirPath = fs::complete(dirPaths[i]);
|
||||||
|
|
||||||
#if !defined(WIN32)
|
if (!fs::exists(dirPath) || !fs::is_directory(dirPath))
|
||||||
DIR *directory;
|
break;
|
||||||
struct dirent *dirinfo;
|
|
||||||
|
|
||||||
if ((directory = opendir(dirPath.c_str())) == NULL)
|
fs::directory_iterator end, it(dirPath);
|
||||||
SLog(EInfo, "Could not open plugin directory");
|
|
||||||
|
|
||||||
while ((dirinfo = readdir(directory)) != NULL) {
|
for (; it != end; ++it) {
|
||||||
std::string fname(dirinfo->d_name);
|
if (!fs::is_regular_file(it->status()))
|
||||||
if (!boost::ends_with(fname, ".dylib") && !boost::ends_with(fname, ".so"))
|
continue;
|
||||||
|
std::string extension(boost::to_lower_copy(it->path().extension()));
|
||||||
|
#if defined(WIN32)
|
||||||
|
if (extension != ".dll")
|
||||||
|
continue;
|
||||||
|
#elif defined(__OSX__)
|
||||||
|
if (extension != ".dylib")
|
||||||
|
continue;
|
||||||
|
#elif defined(__LINUX__)
|
||||||
|
if (extension != ".so")
|
||||||
continue;
|
continue;
|
||||||
std::string fullName = dirPath + "/" + fname;
|
|
||||||
#else
|
#else
|
||||||
HANDLE hFind;
|
#error Unknown operating system!
|
||||||
WIN32_FIND_DATA findFileData;
|
|
||||||
|
|
||||||
if ((hFind = FindFirstFile((dirPath + "\\*.dll").c_str(), &findFileData)) == INVALID_HANDLE_VALUE)
|
|
||||||
SLog(EInfo, "Could not open plugin directory");
|
|
||||||
|
|
||||||
do {
|
|
||||||
std::string fname = findFileData.cFileName;
|
|
||||||
std::string fullName = dirPath + "\\" + fname;
|
|
||||||
#endif
|
#endif
|
||||||
std::string shortName = fname.substr(0, strrchr(fname.c_str(), '.') - fname.c_str());
|
std::string shortName = it->path().stem();
|
||||||
if (seen.find(shortName) != seen.end())
|
if (seen.find(shortName) != seen.end())
|
||||||
continue;
|
continue;
|
||||||
seen.insert(shortName);
|
seen.insert(shortName);
|
||||||
Plugin utility(shortName, fullName);
|
Plugin utility(shortName, it->path());
|
||||||
if (!utility.isUtility())
|
if (!utility.isUtility())
|
||||||
continue;
|
continue;
|
||||||
if (boost::starts_with(shortName, "test_")) {
|
if (boost::starts_with(shortName, "test_")) {
|
||||||
|
@ -122,13 +114,7 @@ void help() {
|
||||||
utilities << ' ';
|
utilities << ' ';
|
||||||
utilities << utility.getDescription() << endl;
|
utilities << utility.getDescription() << endl;
|
||||||
}
|
}
|
||||||
#if !defined(WIN32)
|
|
||||||
}
|
}
|
||||||
closedir(directory);
|
|
||||||
#else
|
|
||||||
} while (FindNextFile(hFind, &findFileData));
|
|
||||||
FindClose(hFind);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << testcases.str() << utilities.str();
|
cout << testcases.str() << utilities.str();
|
||||||
|
@ -277,36 +263,34 @@ int ubi_main(int argc, char **argv) {
|
||||||
int executed = 0, succeeded = 0;
|
int executed = 0, succeeded = 0;
|
||||||
|
|
||||||
for (size_t i=0; i<dirPaths.size(); ++i) {
|
for (size_t i=0; i<dirPaths.size(); ++i) {
|
||||||
std::string dirPath = fs::complete(dirPaths[i]).file_string();
|
fs::path dirPath = fs::complete(dirPaths[i]);
|
||||||
|
|
||||||
#if !defined(WIN32)
|
if (!fs::exists(dirPath) || !fs::is_directory(dirPath))
|
||||||
DIR *directory;
|
break;
|
||||||
struct dirent *dirinfo;
|
|
||||||
|
|
||||||
if ((directory = opendir(dirPath.c_str())) == NULL)
|
fs::directory_iterator end, it(dirPath);
|
||||||
SLog(EInfo, "Could not open plugin directory");
|
|
||||||
|
|
||||||
while ((dirinfo = readdir(directory)) != NULL) {
|
for (; it != end; ++it) {
|
||||||
std::string fname(dirinfo->d_name);
|
if (!fs::is_regular_file(it->status()))
|
||||||
if (!boost::ends_with(fname, ".dylib") && !boost::ends_with(fname, ".so"))
|
continue;
|
||||||
|
std::string extension(boost::to_lower_copy(it->path().extension()));
|
||||||
|
#if defined(WIN32)
|
||||||
|
if (extension != ".dll")
|
||||||
|
continue;
|
||||||
|
#elif defined(__OSX__)
|
||||||
|
if (extension != ".dylib")
|
||||||
|
continue;
|
||||||
|
#elif defined(__LINUX__)
|
||||||
|
if (extension != ".so")
|
||||||
continue;
|
continue;
|
||||||
std::string fullName = dirPath + "/" + fname;
|
|
||||||
#else
|
#else
|
||||||
HANDLE hFind;
|
#error Unknown operating system!
|
||||||
WIN32_FIND_DATA findFileData;
|
|
||||||
|
|
||||||
if ((hFind = FindFirstFile((dirPath + "\\*.dll").c_str(), &findFileData)) == INVALID_HANDLE_VALUE)
|
|
||||||
SLog(EInfo, "Could not open plugin directory");
|
|
||||||
|
|
||||||
do {
|
|
||||||
std::string fname = findFileData.cFileName;
|
|
||||||
std::string fullName = dirPath + "\\" + fname;
|
|
||||||
#endif
|
#endif
|
||||||
std::string shortName = fname.substr(0, strrchr(fname.c_str(), '.') - fname.c_str());
|
std::string shortName = it->path().stem();
|
||||||
if (!boost::starts_with(shortName, "test_") || seen.find(shortName) != seen.end())
|
if (seen.find(shortName) != seen.end() || !boost::starts_with(shortName, "test_"))
|
||||||
continue;
|
continue;
|
||||||
seen.insert(shortName);
|
seen.insert(shortName);
|
||||||
Plugin plugin(shortName, fullName);
|
Plugin plugin(shortName, it->path());
|
||||||
if (!plugin.isUtility())
|
if (!plugin.isUtility())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -321,13 +305,7 @@ int ubi_main(int argc, char **argv) {
|
||||||
|
|
||||||
executed += testCase->getExecuted();
|
executed += testCase->getExecuted();
|
||||||
succeeded += testCase->getSucceeded();
|
succeeded += testCase->getSucceeded();
|
||||||
#if !defined(WIN32)
|
|
||||||
}
|
}
|
||||||
closedir(directory);
|
|
||||||
#else
|
|
||||||
} while (FindNextFile(hFind, &findFileData));
|
|
||||||
FindClose(hFind);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SLog(EInfo, "Ran %i tests, %i succeeded, %i failed.", executed, succeeded, executed-succeeded);
|
SLog(EInfo, "Ran %i tests, %i succeeded, %i failed.", executed, succeeded, executed-succeeded);
|
||||||
|
@ -336,22 +314,26 @@ int ubi_main(int argc, char **argv) {
|
||||||
std::cerr << "A utility name must be supplied!" << endl;
|
std::cerr << "A utility name must be supplied!" << endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
fs::path pluginName(argv[optind]);
|
||||||
|
|
||||||
/* Build the full plugin file name */
|
/* Build the full plugin file name */
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
std::string shortName = std::string("plugins/") + argv[optind] + std::string(".dll");
|
pluginName.replace_extension(".dll");
|
||||||
#elif defined(__OSX__)
|
#elif defined(__OSX__)
|
||||||
std::string shortName = std::string("plugins/") + argv[optind] + std::string(".dylib");
|
pluginName.replace_extension(".dylib");
|
||||||
|
#elif defined(__LINUX__)
|
||||||
|
pluginName.replace_extension(".so");
|
||||||
#else
|
#else
|
||||||
std::string shortName = std::string("plugins/") + argv[optind] + std::string(".so");
|
#error Unknown operating system!
|
||||||
#endif
|
#endif
|
||||||
std::string fullName = fileResolver->resolve(shortName).file_string();
|
fs::path fullName = fileResolver->resolve(fs::path("plugins") / pluginName);
|
||||||
|
|
||||||
if (!fs::exists(fullName)) {
|
if (!fs::exists(fullName)) {
|
||||||
/* Plugin not found! */
|
/* Plugin not found! */
|
||||||
SLog(EError, "Utility \"%s\" not found (run \"mtsutil\" without arguments to "
|
SLog(EError, "Utility \"%s\" not found (run \"mtsutil\" without arguments to "
|
||||||
"see a list of available utilities)", fullName.c_str());
|
"see a list of available utilities)", fullName.file_string().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
SLog(EInfo, "Loading utility \"%s\" ..", argv[optind]);
|
SLog(EInfo, "Loading utility \"%s\" ..", argv[optind]);
|
||||||
Plugin *plugin = new Plugin(argv[optind], fullName);
|
Plugin *plugin = new Plugin(argv[optind], fullName);
|
||||||
if (!plugin->isUtility())
|
if (!plugin->isUtility())
|
||||||
|
|
Loading…
Reference in New Issue