added pluging loader for unix #4313
This commit is contained in:
parent
1d7eb3f5cb
commit
7bff958422
|
@ -76,7 +76,7 @@ if (UNIX)
|
||||||
|
|
||||||
# warnings as errors:
|
# warnings as errors:
|
||||||
# we have a problem with people checking in code with warnings.
|
# 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.
|
# For config.h, detect the libraries, functions, etc.
|
||||||
include(CheckIncludeFiles)
|
include(CheckIncludeFiles)
|
||||||
|
@ -174,7 +174,7 @@ if (UNIX)
|
||||||
CACHE STRING "" FORCE)
|
CACHE STRING "" FORCE)
|
||||||
else()
|
else()
|
||||||
# >= 10.6: Intel only
|
# >= 10.6: Intel only
|
||||||
set(CMAKE_OSX_ARCHITECTURES "i386;x86_64"
|
set(CMAKE_OSX_ARCHITECTURES "i386"
|
||||||
CACHE STRING "" FORCE)
|
CACHE STRING "" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -50,5 +50,5 @@ endif()
|
||||||
add_library(arch STATIC ${sources})
|
add_library(arch STATIC ${sources})
|
||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
target_link_libraries(arch ${libs})
|
target_link_libraries(arch dl ${libs})
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -18,6 +18,22 @@
|
||||||
|
|
||||||
#include "arch/unix/ArchPluginUnix.h"
|
#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()
|
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
|
void
|
||||||
ArchPluginUnix::init(void* eventTarget, IEventQueue* events)
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,5 +31,19 @@ public:
|
||||||
virtual ~ArchPluginUnix();
|
virtual ~ArchPluginUnix();
|
||||||
|
|
||||||
// IArchPlugin overrides
|
// IArchPlugin overrides
|
||||||
|
void load();
|
||||||
void init(void* eventTarget, IEventQueue* events);
|
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);
|
||||||
|
|
|
@ -30,6 +30,7 @@ endif()
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
../../lib/
|
../../lib/
|
||||||
|
../../..
|
||||||
${OPENSSL_INCLUDE}
|
${OPENSSL_INCLUDE}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -65,11 +66,28 @@ if (WIN32)
|
||||||
..\\..\\..\\..\\bin\\${CMAKE_CFG_INTDIR}\\plugins\\
|
..\\..\\..\\..\\bin\\${CMAKE_CFG_INTDIR}\\plugins\\
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
|
if (APPLE)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET ns
|
TARGET ns
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMAND cp
|
COMMAND
|
||||||
..\\..\\..\\..\\lib\\${CMAKE_CFG_INTDIR}\\ns.so
|
mkdir -p
|
||||||
..\\..\\..\\..\\bin\\${CMAKE_CFG_INTDIR}\\plugins\\
|
${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()
|
endif()
|
||||||
|
|
Loading…
Reference in New Issue