#include <malloc.h>
#endif
+#if HAVE_MEMORY_H
+#include <memory.h>
+#endif
+
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "ltdl.h"
+typedef struct lt_dltype_t {
+ struct lt_dltype_t *next;
+ int (*mod_init) __P((void));
+ int (*mod_exit) __P((void));
+ int (*lib_open) __P((lt_dlhandle handle, const char *filename));
+ int (*lib_close) __P((lt_dlhandle handle));
+ __ptr_t (*find_sym) __P((lt_dlhandle handle, const char *symbol));
+} lt_dltype_t, *lt_dltype;
+
+#define LT_DLTYPE_TOP NULL
+
typedef struct lt_dlhandle_t {
struct lt_dlhandle_t *next;
+ lt_dltype_t *type; /* dlopening interface */
char *filename; /* file name */
char *name; /* module name */
int usage; /* usage */
__ptr_t sys; /* system specific data */
} lt_dlhandle_t;
-static int sys_dlinit __P((void));
-static int sys_dlexit __P((void));
-static int sys_dlopen __P((lt_dlhandle handle, const char *filename));
-static int sys_dlclose __P((lt_dlhandle handle));
-static __ptr_t sys_dlsym __P((lt_dlhandle handle, char *symbol));
-static void trim __P((char *dest, const char *s));
+#if ! HAVE_STRDUP
-#ifndef HAVE_STRDUP
+#undef strdup
+#define strdup xstrdup
static char *
strdup(str)
#endif
-#ifndef HAVE_STRRCHR
+#if ! HAVE_STRRCHR
+
+# if HAVE_RINDEX
-static char*
+# define strrchr rindex
+
+# else
+
+# define strrchr xstrrchr
+
+static const char*
strrchr(str, ch)
const char *str;
int ch;
{
- char *p;
+ const char *p;
for (p = str; p != '\0'; p++)
/*NOWORK*/;
return (*p == (char)ch) ? p : NULL;
}
-#endif
-
-#ifdef LIBTOOL_STATIC
-
-/* emulate dynamic linking using dld_preloaded_symbols */
-
-struct dld_symlist
-{
- char *name;
- __ptr_t address;
-};
-
-extern struct dld_symlist dld_preloaded_symbols[];
-
-static int
-sys_dlinit ()
-{
- return 0;
-}
-
-static int
-sys_dlexit ()
-{
- return 0;
-}
-
-static int
-sys_dlopen (handle, filename) lt_dlhandle handle; const char *filename;
-{
- struct dld_symlist *s = dld_preloaded_symbols;
-
- while (s->name) {
- if (!s->address && !strcmp(s->name, filename))
- break;
- s++;
- }
- if (!s->name)
- return 1;
- handle->handle = s;
- return 0;
-}
-
-static int
-sys_dlclose (handle) lt_dlhandle handle;
-{
- return 0;
-}
+# endif
-static __ptr_t
-sys_dlsym (handle, symbol) lt_dlhandle handle; char *symbol;
-{
- struct dld_symlist *s = (struct dld_symlist*)(handle->handle);
-
- if (!s)
- return 0;
- s++;
- while (s->address) {
- if (strcmp(s->name, symbol) == 0)
- return s->address;
- s++;
- }
- return 0;
-}
+#endif
-#else
-#ifdef HAVE_LIBDL
+#if HAVE_LIBDL
/* dynamic linking with dlopen/dlsym */
-#ifdef HAVE_DLFCN_H
-#include <dlfcn.h>
+#if HAVE_DLFCN_H
+# include <dlfcn.h>
#endif
#ifdef RTLD_LAZY
# define DLOPEN_MODE RTLD_LAZY
#else
-#ifdef DL_LAZY
+# ifdef DL_LAZY
# define DLOPEN_MODE DL_LAZY
-#else
+# else
# define DLOPEN_MODE 1
-#endif
+# endif
#endif
static int
-sys_dlinit ()
+dl_init ()
{
return 0;
}
static int
-sys_dlexit ()
+dl_exit ()
{
return 0;
}
static int
-sys_dlopen (handle, filename) lt_dlhandle handle; const char *filename;
+dl_open (handle, filename) lt_dlhandle handle; const char *filename;
{
handle->handle = dlopen(filename, DLOPEN_MODE);
return !(handle->handle);
}
static int
-sys_dlclose (handle) lt_dlhandle handle;
+dl_close (handle) lt_dlhandle handle;
{
return dlclose(handle->handle);
}
static __ptr_t
-sys_dlsym (handle, symbol) lt_dlhandle handle; char *symbol;
+dl_sym (handle, symbol) lt_dlhandle handle; const char *symbol;
{
return dlsym(handle->handle, symbol);
}
-#else
-#ifdef HAVE_SHL_LOAD
+static
+lt_dltype_t
+dl = { LT_DLTYPE_TOP, dl_init, dl_exit,
+ dl_open, dl_close, dl_sym };
+
+#undef LT_DLTYPE_TOP
+#define LT_DLTYPE_TOP &dl
+
+#endif
+
+#if HAVE_SHL_LOAD
/* dynamic linking with shl_load (HP-UX) */
#endif
static int
-sys_dlinit ()
+shl_init ()
{
return 0;
}
static int
-sys_dlexit ()
+shl_exit ()
{
return 0;
}
static int
-sys_dlopen (handle, filename) lt_dlhandle handle; const char *filename;
+shl_open (handle, filename) lt_dlhandle handle; const char *filename;
{
/* Probably too much BIND_* flags */
handle->handle = shl_load (filename, BIND_IMMEDIATE || BIND_FIRST ||
}
static int
-sys_dlclose (handle) lt_dlhandle handle;
+shl_close (handle) lt_dlhandle handle;
{
shl_unload((shl_t) (handle->handle));
return 0;
}
static __ptr_t
-sys_dlsym (handle, symbol) lt_dlhandle handle; char *symbol;
+shl_sym (handle, symbol) lt_dlhandle handle; const char *symbol;
{
int status, i;
struct shl_symbol *sym;
return 0;
}
-#else
-#ifdef HAVE_DLD
+static
+lt_dltype_t
+shl = { LT_DLTYPE_TOP, shl_init, shl_exit,
+ shl_open, shl_close, shl_sym };
+
+#undef LT_DLTYPE_TOP
+#define LT_DLTYPE_TOP &shl
+
+#endif
+
+#if HAVE_DLD
/* dynamic linking with dld */
static int
-sys_dlinit ()
+dld_init ()
{
return 0;
}
static int
-sys_dlexit ()
+dld_exit ()
{
return 0;
}
static int
-sys_dlopen (handle, filename) lt_dlhandle handle; const char *filename;
+dld_open (handle, filename) lt_dlhandle handle; const char *filename;
{
if (dld_link(filename))
return 1;
}
static int
-sys_dlclose (handle) lt_dlhandle handle;
+dld_close (handle) lt_dlhandle handle;
{
dld_unlink_by_file((char*)(handle->handle), 1);
return 0;
}
static __ptr_t
-sys_dlsym (handle, symbol) lt_dlhandle handle; char *symbol;
+dld_sym (handle, symbol) lt_dlhandle handle; const char *symbol;
{
return dld_get_func(symbol);
}
-#else
+static
+lt_dltype_t
+dld = { LT_DLTYPE_TOP, dld_init, dld_exit,
+ dld_open, dld_close, dld_sym };
+
+#undef LT_DLTYPE_TOP
+#define LT_DLTYPE_TOP &dld
+
+#endif
+
#ifdef _WIN32
/* dynamic linking for Win32 */
#include <windows.h>
static int
-sys_dlinit ()
+wll_init ()
{
return 0;
}
static int
-sys_dlexit ()
+wll_exit ()
{
return 0;
}
static int
-sys_dlopen (handle, filename) lt_dlhandle handle; const char *filename;
+wll_open (handle, filename) lt_dlhandle handle; const char *filename;
{
handle->handle = LoadLibrary(filename);
return !(handle->handle);
}
static int
-sys_dlclose (handle) lt_dlhandle handle;
+wll_close (handle) lt_dlhandle handle;
{
FreeLibrary(handle->handle);
return 0;
}
static __ptr_t
-sys_dlsym (handle, symbol) lt_dlhandle handle; char *symbol;
+wll_sym (handle, symbol) lt_dlhandle handle; const char *symbol;
{
return GetProcAddress(handle->handle, symbol);
}
-#else
+static
+lt_dltype_t
+wll = { LT_DLTYPE_TOP, wll_init, wll_exit,
+ wll_open, wll_close, wll_sym };
-/* no dynamic linking available */
+#undef LT_DLTYPE_TOP
+#define LT_DLTYPE_TOP &wll
+
+#endif
+
+#if HAVE_DLPREOPEN
+
+/* emulate dynamic linking using dld_preloaded_symbols */
+
+struct dld_symlist
+{
+ char *name;
+ __ptr_t address;
+};
+
+extern struct dld_symlist dld_preloaded_symbols[];
static int
-sys_dlinit ()
+dldpre_init ()
{
- return 1; /* dlopen not supported */
+ return 0;
}
static int
-sys_dlexit ()
+dldpre_exit ()
{
return 0;
}
static int
-sys_dlopen (handle, filename) lt_dlhandle handle; const char *filename;
+dldpre_open (handle, filename) lt_dlhandle handle; const char *filename;
{
- return 1; /* always report an error */
+ struct dld_symlist *s = dld_preloaded_symbols;
+
+ while (s->name) {
+ if (!s->address && !strcmp(s->name, filename))
+ break;
+ s++;
+ }
+ if (!s->name)
+ return 1;
+ handle->handle = s;
+ return 0;
}
static int
-sys_dlclose (handle) lt_dlhandle handle;
+dldpre_close (handle) lt_dlhandle handle;
{
return 0;
}
static __ptr_t
-sys_dlsym (handle, symbol) lt_dlhandle handle; char *symbol;
+dldpre_sym (handle, symbol) lt_dlhandle handle; const char *symbol;
{
+ struct dld_symlist *s = (struct dld_symlist*)(handle->handle);
+
+ if (!s)
+ return 0;
+ s++;
+ while (s->address) {
+ if (strcmp(s->name, symbol) == 0)
+ return s->address;
+ s++;
+ }
return 0;
}
-#endif
-#endif
-#endif
-#endif
+static
+lt_dltype_t
+dldpre = { LT_DLTYPE_TOP, dldpre_init, dldpre_exit,
+ dldpre_open, dldpre_close, dldpre_sym };
+
+#undef LT_DLTYPE_TOP
+#define LT_DLTYPE_TOP &dldpre
+
#endif
static lt_dlhandle handles;
static int initialized = 0;
+static lt_dltype types = LT_DLTYPE_TOP;
+#undef LT_DLTYPE_TOP
+
int
lt_dlinit ()
{
+ lt_dltype *type = &types;
+ int typecount = 0;
+
if (initialized) { /* Initialize only at first call. */
initialized++;
return 0;
}
handles = 0;
- if (sys_dlinit())
+
+ while (*type) {
+ if ((*type)->mod_init())
+ *type = (*type)->next; /* Remove it from the list */
+ else {
+ type = &(*type)->next; /* Keep it */
+ ++typecount;
+ }
+ }
+ if (typecount == 0)
return 1;
initialized = 1;
return 0;
int
lt_dlexit ()
{
+ lt_dltype type = types;
int error;
if (!initialized)
if (lt_dlclose(handles))
error = 1;
initialized = 0;
- if (sys_dlexit())
- error = 1;
+ while (type) {
+ if (type->mod_exit())
+ ++error;
+ type = type->next;
+ }
return error;
}
*dest = '\0';
}
+static
+int
+tryall_dlopen (handle, fullname) lt_dlhandle handle; const char *fullname;
+{
+ lt_dltype type = types;
+ while (type) {
+ if (type->lib_open(handle, fullname) == 0)
+ break;
+ type = type->next;
+ }
+ handle->type = type;
+ return !type;
+}
+
lt_dlhandle
lt_dlopen (filename) const char *filename;
{
lt_dlhandle handle, cur;
FILE *file;
- char tmp[1024], dir[512];
- char *basename, *ext;
+ char tmp[1024], dir[1024]; /* FIXME: unchecked buffer */
+ const char *basename, *ext;
/* check whether the module was already opened */
cur = handles;
basename = strrchr(filename, '/');
if (basename)
basename++;
+ else
+ basename = filename;
strncpy(dir, filename, basename - filename);
dir[basename - filename] = '\0';
/* check whether we open a libtool module (.la extension) */
ext = strrchr(basename, '.');
if (ext && strcmp(ext, ".la") == 0) {
- char dlname[256], libdir[512], deps[512];
- char fullname[512];
+ char dlname[1024], libdir[1024], deps[1024];
+ char fullname[1024], old_name[1024]; /* FIXME: unchecked */
+ lt_dltype type;
+
+ dlname[0] = libdir[0] = deps[0] = old_name[0] = '\0';
file = fopen(filename, "r"); /* FIXME: portable? */
if (!file) {
- free(handle);
+ free(handle);
return 0;
}
while (!feof(file)) {
if (strncmp(tmp, "dependency_libs=", 16) == 0)
trim(deps, &tmp[16]);
else
-#ifdef STATIC
- if (strncmp(tmp, "old_library=", 12) == 0)
- trim(dlname, &tmp[12]);
-#else
if (strncmp(tmp, "dlname=", 7) == 0)
trim(dlname, &tmp[7]);
-#endif
+ else
+ if (strncmp(tmp, "old_library=", 12) == 0)
+ trim(old_name, &tmp[12]);
}
fclose(file);
- if (!strlen(dlname)) { /* filename not found */
+ if (!*dlname && !*old_name) { /* filename not found */
free(handle);
return 0;
}
/* search the module */
-#ifdef STATIC
- if (sys_dlopen(handle, dlname)) {
- free(handle);
- return 0;
- }
- handle->filename = strdup(dlname);
-#else
strcpy(fullname, libdir);
strcat(fullname, "/");
strcat(fullname, dlname);
- if (sys_dlopen(handle, fullname)) {
+ if (!*dlname || tryall_dlopen(handle, fullname)) {
strcpy(fullname, dir);
strcat(fullname, dlname);
- if (sys_dlopen(handle, fullname)) {
+ if (!*dlname || tryall_dlopen(handle, fullname)) {
strcpy(fullname, dir);
strcat(fullname, ".libs/");
strcat(fullname, dlname);
- if (sys_dlopen(handle, fullname)) {
- free(handle);
- return 0;
+ if (!*dlname || tryall_dlopen(handle, fullname)) {
+ strcpy(fullname, old_name);
+ if (!*old_name ||
+ tryall_dlopen(handle, fullname)) {
+ free(handle);
+ return 0;
+ }
}
}
}
handle->filename = strdup(fullname);
-#endif
/* extract the module name from the file name */
strcpy(tmp, basename);
tmp[ext - basename] = '\0';
handle->name = strdup(tmp);
} else {
/* not a libtool module */
- if (sys_dlopen(handle, filename)) {
+ if (tryall_dlopen(handle, filename)) {
free(handle);
return 0;
}
last->next = handle->next;
else
handles = handle->next;
- error = sys_dlclose(handle);
+ error = handle->type->lib_close(handle);
free(handle->filename);
if (handle->name)
free(handle->name);
}
__ptr_t
-lt_dlsym (handle, symbol) lt_dlhandle handle; char *symbol;
+lt_dlsym (handle, symbol) lt_dlhandle handle; const char *symbol;
{
char sym[128];
__ptr_t address;
strcat(sym, "_LTX_");
strcat(sym, symbol);
/* try "modulename_LTX_symbol" */
- address = sys_dlsym(handle, sym);
+ address = handle->type->find_sym(handle, sym);
if (address)
return address;
}
/* prefix symbol with leading underscore */
strcpy(sym, "_");
strcat(sym, symbol);
- return sys_dlsym(handle, sym);
+ return handle->type->find_sym(handle, sym);
#else
- return sys_dlsym(handle, symbol);
+ return handle->type->find_sym(handle, symbol);
#endif
}