added pluging loader for unix #4313

This commit is contained in:
XinyuHou 2015-01-09 13:47:35 +00:00
parent 1d7eb3f5cb
commit 7bff958422
5 changed files with 160 additions and 10 deletions

View File

@ -76,7 +76,7 @@ if (UNIX)
# warnings as errors:
# we have a problem with people checking in code with warnings.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -fPIC")
# For config.h, detect the libraries, functions, etc.
include(CheckIncludeFiles)
@ -174,7 +174,7 @@ if (UNIX)
CACHE STRING "" FORCE)
else()
# >= 10.6: Intel only
set(CMAKE_OSX_ARCHITECTURES "i386;x86_64"
set(CMAKE_OSX_ARCHITECTURES "i386"
CACHE STRING "" FORCE)
endif()

View File

@ -50,5 +50,5 @@ endif()
add_library(arch STATIC ${sources})
if (UNIX)
target_link_libraries(arch ${libs})
target_link_libraries(arch dl ${libs})
endif()

View File

@ -18,6 +18,22 @@
#include "arch/unix/ArchPluginUnix.h"
#include "arch/unix/XArchUnix.h"
#include "base/IEventQueue.h"
#include "base/Event.h"
#include "base/Log.h"
#include <vector>
#include <sys/types.h>
#include <dirent.h>
#include <dlfcn.h>
typedef int (*initFunc)(void (*sendEvent)(const char*, void*), void (*log)(const char*));
typedef void* (*invokeFunc)(const char*, void*);
void* g_eventTarget = NULL;
IEventQueue* g_events = NULL;
ArchPluginUnix::ArchPluginUnix()
{
}
@ -26,7 +42,109 @@ ArchPluginUnix::~ArchPluginUnix()
{
}
void
ArchPluginUnix::load()
{
String pluginsDir = getPluginsDir();
LOG((CLOG_DEBUG "plugins dir: %s", pluginsDir.c_str()));
struct dirent* de = NULL;
DIR* dir = NULL;
dir = opendir(pluginsDir.c_str());
if (dir == NULL) {
LOG((CLOG_DEBUG "can't open plugins dir: %s",
pluginsDir.c_str()));
return;
}
std::vector<String> plugins;
while ((de = readdir(dir)) != NULL) {
// ignore hidden files and diretories like .. and .
if (de->d_name[0] != '.') {
LOG((CLOG_DEBUG "load plugin %s", de->d_name));
plugins.push_back(de->d_name);
}
}
closedir(dir);
std::vector<String>::iterator it;
for (it = plugins.begin(); it != plugins.end(); ++it) {
LOG((CLOG_DEBUG "loading plugin: %s", (*it).c_str()));
String path = String(getPluginsDir()).append("/").append(*it);
void* library = dlopen(path.c_str(), RTLD_LAZY);
if (library == NULL) {
throw XArch(dlerror());
}
String filename = synergy::string::removeFileExt(*it);
m_pluginTable.insert(std::make_pair(filename, library));
}
}
void
ArchPluginUnix::init(void* eventTarget, IEventQueue* events)
{
g_eventTarget = eventTarget;
g_events = events;
PluginTable::iterator it;
for (it = m_pluginTable.begin(); it != m_pluginTable.end(); it++) {
initFunc initPlugin = (initFunc)dlsym(it->second, "init");
initPlugin(&sendEvent, &log);
}
}
bool
ArchPluginUnix::exists(const char* name)
{
PluginTable::iterator it;
it = m_pluginTable.find(name);
return it != m_pluginTable.end() ? true : false;
}
void*
ArchPluginUnix::invoke(
const char* plugin,
const char* command,
void* args)
{
PluginTable::iterator it;
it = m_pluginTable.find(plugin);
if (it != m_pluginTable.end()) {
invokeFunc invokePlugin = (invokeFunc)dlsym(it->second, "invoke");
return invokePlugin(command, args);
}
else {
LOG((CLOG_DEBUG "invoke command failed, plugin: %s command: %s",
plugin, command));
return NULL;
}
}
String
ArchPluginUnix::getPluginsDir()
{
#if WINAPI_XWINDOWS
return "/usr/lib/synergy/plugin";
#else
// TODO: pluging should be in bundle in the final release
return "/Users/xinyu/Projects/synergy/bin/plugins";
#endif
}
void
sendEvent(const char* eventName, void* data)
{
LOG((CLOG_DEBUG5 "plugin sending event"));
Event::Type type = g_events->getRegisteredType(eventName);
g_events->addEvent(Event(type, g_eventTarget, data));
}
void
log(const char* text)
{
LOG((CLOG_DEBUG "plugin: %s", text));
}

View File

@ -31,5 +31,19 @@ public:
virtual ~ArchPluginUnix();
// IArchPlugin overrides
void load();
void init(void* eventTarget, IEventQueue* events);
bool exists(const char* name);
virtual void* invoke(const char* pluginName,
const char* functionName,
void* args);
private:
String getPluginsDir();
private:
PluginTable m_pluginTable;
};
void sendEvent(const char* text, void* data);
void log(const char* text);

View File

@ -30,6 +30,7 @@ endif()
include_directories(
../../lib/
../../..
${OPENSSL_INCLUDE}
)
@ -65,11 +66,28 @@ if (WIN32)
..\\..\\..\\..\\bin\\${CMAKE_CFG_INTDIR}\\plugins\\
)
else()
add_custom_command(
TARGET ns
POST_BUILD
COMMAND cp
..\\..\\..\\..\\lib\\${CMAKE_CFG_INTDIR}\\ns.so
..\\..\\..\\..\\bin\\${CMAKE_CFG_INTDIR}\\plugins\\
)
if (APPLE)
add_custom_command(
TARGET ns
POST_BUILD
COMMAND
mkdir -p
${CMAKE_SOURCE_DIR}/bin/plugins
&&
cp
${CMAKE_SOURCE_DIR}/lib/${CMAKE_CFG_INTDIR}/libns.dylib
${CMAKE_SOURCE_DIR}/bin/plugins/
)
else()
add_custom_command(
TARGET ns
POST_BUILD
COMMAND mkdir -p
../../../../../bin/plugins
&&
cp
../../../../../lib/libns.so
../../../../../bin/plugins/
)
endif()
endif()