[collectd] [PATCH] prefer glibc's dlopen() over libtool's dlopen()
Bruno Prémont
bonbons at linux-vserver.org
Wed Mar 21 21:47:28 CET 2012
Use libc's dlopen/dlsym instead of libtool's ones when available
Patch below changes collectd's plugin.c to use dlopen/dlsym/dlerror
from libc when dlfcn.h is available instead of using libtool
equivalents.
This reduces libtool to a build-dependency only instead of also being a
runtime dependency.
Signed-off-by: Bruno Prémont <bonbons at linux-vserver.org>
---
configure.in | 4 ++++
src/Makefile.am | 3 +++
src/plugin.c | 40 +++++++++++++++++++++++++++++++++++++++-
3 files changed, 46 insertions(+), 1 deletions(-)
diff -NurpP collectd-5.0.1.orig/configure.in collectd-5.0.1/configure.in
--- collectd-5.0.1.orig/configure.in 2011-10-30 23:42:18.042568148 +0000
+++ collectd-5.0.1/configure.in 2011-10-30 23:44:43.809613958 +0000
@@ -263,6 +263,9 @@ AC_CHECK_HEADERS(netinet/udp.h, [], [],
#endif
])
+# For plugin
+AC_CHECK_HEADERS(dlfcn.h, [have_dlfcn_h="yes"], [have_dlfcn_h="no"])
+
# For cpu modules
AC_CHECK_HEADERS(sys/dkstat.h)
if test "x$ac_system" = "xDarwin"
@@ -604,6 +607,7 @@ AC_CHECK_FUNCS(nanosleep,
[nanosleep_needs_posix4="yes"],
AC_MSG_ERROR(cannot find nanosleep))))
+AM_CONDITIONAL(BUILD_WITH_LIBDL, test "x$have_dlfcn_h" = "xyes")
AM_CONDITIONAL(BUILD_WITH_LIBRT, test "x$clock_gettime_needs_rt" = "xyes" || test "x$nanosleep_needs_rt" = "xyes")
AM_CONDITIONAL(BUILD_WITH_LIBPOSIX4, test "x$clock_gettime_needs_posix4" = "xyes" || test "x$nanosleep_needs_posix4" = "xyes")
diff -NurpP collectd-5.0.1.orig/src/Makefile.am collectd-5.0.1/src/Makefile.am
--- collectd-5.0.1.orig/src/Makefile.am 2011-10-30 23:42:17.962617577 +0000
+++ collectd-5.0.1/src/Makefile.am 2011-10-30 23:45:05.687035350 +0000
@@ -47,6 +47,9 @@ collectd_LDADD =
collectd_DEPENDENCIES =
# Link to these libraries..
+if BUILD_WITH_LIBDL
+collectd_LDADD += -ldl
+endif
if BUILD_WITH_LIBRT
collectd_LDADD += -lrt
endif
diff -NurpP collectd-5.0.1.orig/src/plugin.c collectd-5.0.1/src/plugin.c
--- collectd-5.0.1.orig/src/plugin.c 2011-10-14 20:49:49.000000000 +0000
+++ collectd-5.0.1/src/plugin.c 2011-10-30 23:46:38.656077559 +0000
@@ -23,7 +23,11 @@
#include "collectd.h"
#include "utils_complain.h"
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#else
#include <ltdl.h>
+#endif
#if HAVE_PTHREAD_H
# include <pthread.h>
@@ -277,8 +281,41 @@ static int plugin_unregister (llist_t *l
*/
static int plugin_load_file (char *file, uint32_t flags)
{
- lt_dlhandle dlh;
void (*reg_handle) (void);
+#if HAVE_DLFCN_H
+ void *dlh;
+
+ dlh = dlopen(file, RTLD_NOW | (flags & PLUGIN_FLAGS_GLOBAL ? RTLD_GLOBAL : RTLD_LOCAL));
+ if (dlh == NULL)
+ {
+ char errbuf[1024] = "";
+
+ ssnprintf (errbuf, sizeof (errbuf),
+ "dlopen (\"%s\") failed: %s. "
+ "The most common cause for this problem are "
+ "missing dependencies. Use ldd(1) to check "
+ "the dependencies of the plugin "
+ "/ shared object.",
+ file, dlerror ());
+
+ ERROR ("%s", errbuf);
+ /* Make sure this is printed to STDERR in any case, but also
+ * make sure it's printed only once. */
+ if (list_log != NULL)
+ fprintf (stderr, "ERROR: %s\n", errbuf);
+
+ return (1);
+ }
+
+ if ((reg_handle = (void (*) (void)) dlsym(dlh, "module_register")) == NULL)
+ {
+ WARNING ("Couldn't find symbol \"module_register\" in \"%s\": %s\n",
+ file, dlerror ());
+ dlclose(dlh);
+ return (-1);
+ }
+#else
+ lt_dlhandle dlh;
lt_dlinit ();
lt_dlerror (); /* clear errors */
@@ -328,6 +365,7 @@ static int plugin_load_file (char *file,
lt_dlclose (dlh);
return (-1);
}
+#endif
(*reg_handle) ();
More information about the collectd
mailing list