apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Joe Orton <jor...@redhat.com>
Subject [PATCH] apr_dso_load2() with flags support
Date Fri, 09 Sep 2005 11:05:06 GMT
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);

Mime
View raw message