Any objections? This adds support for the usual RTLD_* flags to be
specified by the caller along with the glibc-specific and very useful
RTLD_DEEPBIND; any other implementation-specific flags can be added too
of course.
Index: include/apr_dso.h
===================================================================
--- include/apr_dso.h (revision 279575)
+++ include/apr_dso.h (working copy)
@@ -48,13 +48,53 @@
*/
typedef void * apr_dso_handle_sym_t;
+/**
+ * @defgroup apr_dso_open_flags DSO open flags
+ * @{
+ */
+#define APR_DSO_LAZY (0x0001) /**< Resolve symbols lazily;
+ undefined symbols will not
+ be noticed until used */
+#define APR_DSO_NOW (0x0002) /**< Resolve symbols at load time;
+ the DSO will fail to load if
+ symbols are undefined */
+#define APR_DSO_GLOBAL (0x0004) /**< Define symbols of loaded DSO
+ globally; they can be used by
+ subsequently loaded libraries */
+#define APR_DSO_LOCAL (0x0008) /**< Define symbols of loaded DSO
+ locally; they will not be visible
+ to subsequently loaded
+ libraries */
+#define APR_DSO_DEEPBIND (0x0010) /**< Resolve undefined symbols in
+ loaded libraries first in their
+ dependants then in global
+ scope. */
+
+#define APR_DSO_DEFAULT (0x0000) /**< Use default behaviour */
+
+/** @} */
+
/**
+ * Load a DSO. Any flags passed are taken as hints and may or
+ * may not be supported by the implementation. The flags
+ * APR_DSO_LAZY and APR_DSO_NOW are mutually exclusive.
+ * The flags APR_DSO_GLOBAL and APR_DSO_LAZY are mutually
+ * exclusive.
+ * @param handle Location to store new handle for the DSO.
+ * @param flags Advisory flags
+ * @param path Path to the DSO library
+ * @param pool Pool to use.
+ */
+APR_DECLARE(apr_status_t) apr_dso_load2(apr_dso_handle_t **handle,
+ const char *path,
+ apr_uint32_t flags,
+ apr_pool_t *pool);
+
+/**
* Load a DSO library.
* @param res_handle Location to store new handle for the DSO.
* @param path Path to the DSO library
* @param ctx Pool to use.
- * @bug We aught to provide an alternative to RTLD_GLOBAL, which
- * is the only supported method of loading DSOs today.
*/
APR_DECLARE(apr_status_t) apr_dso_load(apr_dso_handle_t **res_handle,
const char *path, apr_pool_t *ctx);
Index: dso/unix/dso.c
===================================================================
--- dso/unix/dso.c (revision 279575)
+++ dso/unix/dso.c (working copy)
@@ -77,9 +77,49 @@
return APR_SUCCESS;
}
-APR_DECLARE(apr_status_t) apr_dso_load(apr_dso_handle_t **res_handle,
- const char *path, apr_pool_t *pool)
+#ifdef DSO_USE_DLFCN
+/* Map APR_DSO_* flags to native RTLD_* flags. */
+static int dso_map_flags(apr_uint32_t flags)
{
+ int native = 0;
+
+ /* Default behaviour... */
+ if (flags == 0) {
+ flags = APR_DSO_GLOBAL | APR_DSO_NOW | APR_DSO_DEEPBIND;
+ }
+
+ if (flags & APR_DSO_GLOBAL) {
+ native |= RTLD_GLOBAL;
+ }
+#ifdef RTLD_LOCAL
+ else if (flags & APR_DSO_LOCAL) {
+ native |= RTLD_LOCAL;
+ }
+#endif
+
+ if (flags & APR_DSO_NOW) {
+ native |= RTLD_NOW;
+ }
+#ifdef RTLD_LAZY
+ else if (flags & APR_DSO_LAZY) {
+ native |= RTLD_LAZY;
+ }
+#endif
+
+#ifdef RTLD_DEEPBIND
+ if (flags & APR_DSO_DEEPBIND) {
+ native |= RTLD_DEEPBIND;
+ }
+
+ return native;
+#endif
+}
+#endif /* DSO_USE_DLFCN */
+
+APR_DECLARE(apr_status_t) apr_dso_load2(apr_dso_handle_t **res_handle,
+ const char *path, apr_uint32_t flags,
+ apr_pool_t *pool)
+{
#if defined(DSO_USE_SHL)
shl_t os_handle = shl_load(path, BIND_IMMEDIATE, 0L);
@@ -117,13 +157,12 @@
}
#elif defined(DSO_USE_DLFCN)
+ int os_flags = dso_map_flags(flags);
#if defined(OSF1) || defined(SEQUENT) || defined(SNI) ||\
(defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)) ||\
defined(__DragonFly__)
- void *os_handle = dlopen((char *)path, RTLD_NOW | RTLD_GLOBAL);
-
+ void *os_handle = dlopen((char *)path, os_flags);
#else
- int flags = RTLD_NOW | RTLD_GLOBAL;
void *os_handle;
#ifdef _AIX
if (strchr(path + 1, '(') && path[strlen(path) - 1] == ')')
@@ -133,10 +172,10 @@
* dlopen() support for such a library requires that the
* RTLD_MEMBER flag be enabled.
*/
- flags |= RTLD_MEMBER;
+ os_flags |= RTLD_MEMBER;
}
#endif
- os_handle = dlopen(path, flags);
+ os_handle = dlopen(path, os_flags);
#endif
#endif /* DSO_USE_x */
@@ -163,7 +202,13 @@
return APR_SUCCESS;
}
-
+
+APR_DECLARE(apr_status_t) apr_dso_load(apr_dso_handle_t **handle,
+ const char *path, apr_pool_t *pool)
+{
+ return apr_dso_load2(handle, path, APR_DSO_DEFAULT, pool);
+}
+
APR_DECLARE(apr_status_t) apr_dso_unload(apr_dso_handle_t *handle)
{
return apr_pool_cleanup_run(handle->pool, handle, dso_cleanup);