summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriele Svelto <gabriele.svelto@gmail.com>2012-05-08 20:17:01 +0200
committerMartin Sustrik <sustrik@250bpm.com>2012-05-12 12:13:19 +0200
commite1dff473a625cdbecbaddb89d48fc675efea09f0 (patch)
tree3bbed0ac0a82c3b719fdeaa71c04c66966abfa8a
parent0b1bfac99a01db54396875ca49987f4117061990 (diff)
Enabled plug-in loading on all hosts with support for dlopen()
Previously the code used for loading plug-ins would be built only on Linux hosts. Now the required functions are checked for and plug-in loading code is enabled if those are present on all platforms. Using lstat() to check for file types also increases portability to hosts that do not have the dirent.d_type field. If shared libraries support is disabled plug-ins will also be automatically disabled. Signed-off-by: Gabriele Svelto <gabriele.svelto@gmail.com>
-rw-r--r--configure.ac36
-rw-r--r--src/ctx.cpp45
-rw-r--r--src/ctx.hpp7
3 files changed, 69 insertions, 19 deletions
diff --git a/configure.ac b/configure.ac
index 339cc37..50b4457 100644
--- a/configure.ac
+++ b/configure.ac
@@ -99,8 +99,6 @@ AS_CASE(["${host_os}"],
AC_DEFINE([XS_HAVE_ANDROID], [1], [Have Android OS])
]
)
-
- AC_CHECK_LIB([dl], [dlopen])
],
[*solaris*], [
AC_DEFINE([XS_HAVE_SOLARIS], [1], [Have Solaris OS])
@@ -191,7 +189,11 @@ LIBXS_CHECK_DOC_BUILD
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([ \
+ link.h \
+ dirent.h \
+ dlfcn.h \
errno.h \
+ fcntl.h \
arpa/inet.h \
netinet/tcp.h \
netinet/in.h \
@@ -199,6 +201,7 @@ AC_CHECK_HEADERS([ \
stdlib.h \
string.h \
sys/socket.h \
+ sys/stat.h \
sys/time.h \
sys/types.h \
time.h \
@@ -374,6 +377,34 @@ AS_IF([test "x$enable_libzmq" != "xno"], [
libxs_libzmq="yes"
])
+# Plug-in support
+AC_ARG_ENABLE([plugins], [AS_HELP_STRING([--enable-plugins],
+ [enable plugins [default=auto]])],
+ [enable_plugins=$enableval], [enable_plugins=auto])
+
+AS_IF([test "x$enable_plugins" != "xno"], [
+ # Check if libdl is required, then check for dlopen and lstat, they are
+ # both needed to enable plug-in support
+ AC_SEARCH_LIBS([dlopen], [dl])
+ AC_CHECK_FUNCS([lstat dlopen], [], [
+ AS_IF([test "x$enable_plugins" = "xyes"], [
+ AC_MSG_ERROR([Plugins support not available])
+ ], [
+ AC_MSG_WARN([Plugins support disabled])
+ enable_plugins=no
+ ])
+ ])
+
+ # If shared library support is disabled disable plugins support
+ AS_IF([test "x$enable_shared" = "xno"], [
+ AC_MSG_WARN([Shared library support disabled, disabling plug-ins])
+ enable_plugins=no
+ ], [
+ enable_plugins=yes
+ AC_DEFINE([XS_HAVE_PLUGINS], [1], [Whether plugins support is enabled])
+ ])
+])
+
# PGM extension
libxs_pgm_ext="no"
@@ -525,6 +556,7 @@ Configuration for $PACKAGE_STRING
Polling system: $libxs_cv_poller
Disable eventfd: $xs_disable_eventfd
Build libzmq compatibility library and headers: $libxs_libzmq
+ Plugins support: $enable_plugins
PGM extension: $with_pgm_ext
Use system-provided PGM library: $with_system_pgm_ext
Build documentation: $libxs_build_doc
diff --git a/src/ctx.cpp b/src/ctx.cpp
index f5d9719..063f96c 100644
--- a/src/ctx.cpp
+++ b/src/ctx.cpp
@@ -23,12 +23,27 @@
#if defined XS_HAVE_WINDOWS
#include "windows.hpp"
#else
-#include <unistd.h>
-#endif
-
-#if defined XS_HAVE_LINUX
-#include <dlfcn.h>
-#include <dirent.h>
+# if HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+# if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+# if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+# endif
+# if HAVE_DLFCN_H
+# include <dlfcn.h>
+# endif
+# if HAVE_LINK_H
+# include <link.h>
+# endif
+# if HAVE_FCNTL_H
+# include <fcntl.h>
+# endif
+# if HAVE_DIRENT_H
+# include <dirent.h>
+# endif
#endif
#include <new>
@@ -114,7 +129,7 @@ next:
BOOL brc = FindClose (fh);
win_assert (brc != 0);
-#elif defined XS_HAVE_LINUX
+#elif XS_HAVE_PLUGINS
// Load all the installed plug-ins.
std::string path (XS_PREFIX_PATH);
@@ -126,12 +141,17 @@ next:
errno_assert (dp);
dirent dir, *dirp;
+ struct stat stats;
+
while (true) {
rc = readdir_r (dp, &dir, &dirp);
assert (rc == 0);
if (!dirp)
break;
- if (dir.d_type == DT_REG) {
+
+ rc = lstat (dirp->d_name, &stats);
+
+ if ((rc == 0) && S_ISREG (stats.st_mode)) {
// Ignore the files without .xsp extension.
std::string file = dir.d_name;
@@ -139,7 +159,7 @@ next:
continue;
if (file.substr (file.size () - 4) != ".xsp")
continue;
-
+
// Open the specified dynamic library.
std::string filename = path + "/" + file;
void *dl = dlopen (filename.c_str (), RTLD_LOCAL | RTLD_NOW);
@@ -260,7 +280,7 @@ int xs::ctx_t::terminate ()
it != plugins.end (); ++it)
FreeLibrary (*it);
opt_sync.unlock ();
-#elif defined XS_HAVE_LINUX
+#elif XS_HAVE_PLUGINS
opt_sync.lock ();
for (plugins_t::iterator it = plugins.begin ();
it != plugins.end (); ++it)
@@ -412,7 +432,7 @@ void xs::ctx_t::destroy_socket (class socket_base_t *socket_)
// Free the associared thread slot.
uint32_t tid = socket_->get_tid ();
empty_slots.push_back (tid);
- slots [tid] = NULL;
+ slots [tid] = NULL;
// Remove the socket from the list of sockets.
sockets.erase (socket_);
@@ -497,7 +517,7 @@ void xs::ctx_t::unregister_endpoints (socket_base_t *socket_)
}
++it;
}
-
+
endpoints_sync.unlock ();
}
@@ -528,4 +548,3 @@ xs::endpoint_t xs::ctx_t::find_endpoint (const char *addr_)
// is a global variable. Thus, even sockets created in different contexts have
// unique IDs.
xs::atomic_counter_t xs::ctx_t::max_socket_id;
-
diff --git a/src/ctx.hpp b/src/ctx.hpp
index 7b0b74b..8e2fd03 100644
--- a/src/ctx.hpp
+++ b/src/ctx.hpp
@@ -54,7 +54,7 @@ namespace xs
// Context object encapsulates all the global state associated with
// the library.
-
+
class ctx_t
{
public:
@@ -173,7 +173,7 @@ namespace xs
#if defined XS_HAVE_WINDOWS
typedef std::vector <HMODULE> plugins_t;
plugins_t plugins;
-#elif defined XS_HAVE_LINUX
+#elif defined XS_HAVE_PLUGINS
typedef std::vector <void*> plugins_t;
plugins_t plugins;
#endif
@@ -185,8 +185,7 @@ namespace xs
ctx_t (const ctx_t&);
const ctx_t &operator = (const ctx_t&);
};
-
+
}
#endif
-