#else
#ifdef HAVE_DLFCN_H
-
-#include <dlfcn.h>
+# include <dlfcn.h>
+# define HAVE_DLINFO 1
+# if defined(_AIX) || defined(__CYGWIN__) || \
+ defined(__SCO_VERSION__) || defined(_SCO_ELF) || \
+ (defined(__OpenBSD__) && !defined(RTLD_SELF))
+# undef HAVE_DLINFO
+# endif
#endif
/* Part of the hack in "dlfcn_load" ... */
static char *dlfcn_merger(DSO *dso, const char *filespec1,
const char *filespec2);
static int dlfcn_pathbyaddr(void *addr,char *path,int sz);
+static void *dlfcn_globallookup(const char *name);
static DSO_METHOD dso_meth_dlfcn = {
"OpenSSL 'dlfcn' shared library method",
dlfcn_merger,
NULL, /* init */
NULL, /* finish */
- dlfcn_pathbyaddr
+ dlfcn_pathbyaddr,
+ dlfcn_globallookup
};
DSO_METHOD *DSO_METHOD_dlfcn(void)
}
/* If the first file specification is a rooted path, it rules.
same goes if the second file specification is missing. */
- if (!filespec2 || filespec1[0] == '/')
+ if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/'))
{
merged = OPENSSL_malloc(strlen(filespec1) + 1);
if(!merged)
{
- DSOerr(DSO_F_DLFCN_MERGER,
- ERR_R_MALLOC_FAILURE);
+ DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
return(NULL);
}
strcpy(merged, filespec1);
{
int spec2len, len;
- spec2len = (filespec2 ? strlen(filespec2) : 0);
+ spec2len = strlen(filespec2);
len = spec2len + (filespec1 ? strlen(filespec1) : 0);
if(filespec2 && filespec2[spec2len - 1] == '/')
static int dlfcn_pathbyaddr(void *addr,char *path,int sz)
{
+#ifdef HAVE_DLINFO
Dl_info dli;
int len;
}
ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
+#endif
return -1;
}
+
+static void *dlfcn_globallookup(const char *name)
+ {
+ void *ret = NULL,*handle = dlopen(NULL,RTLD_LAZY);
+
+ if (handle)
+ {
+ ret = dlsym(handle,name);
+ dlclose(handle);
+ }
+
+ return ret;
+ }
#endif /* DSO_DLFCN */