1 /* ltdl.c -- system independent dlopen wrapper
2 Copyright (C) 1998-1999 Free Software Foundation, Inc.
3 Originally by Thomas Tanner <tanner@ffii.org>
4 This file is part of GNU Libtool.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 As a special exception to the GNU Library General Public License,
12 if you distribute this file as part of a program that uses GNU libtool
13 to create libraries and programs, you may include it under the same
14 distribution terms that you use for the rest of that program.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Library General Public License for more details.
21 You should have received a copy of the GNU Library General Public
22 License along with this library; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 #define _LTDL_COMPILE_
63 /* max. filename length */
64 #ifndef LTDL_FILENAME_MAX
65 #define LTDL_FILENAME_MAX 1024
68 #undef LTDL_READTEXT_MODE
69 /* fopen() mode flags for reading a text file */
71 #define LTDL_READTEXT_MODE "rt"
73 #define LTDL_READTEXT_MODE "r"
76 #undef LTDL_SYMBOL_LENGTH
77 /* This is the maximum symbol size that won't require malloc/free */
78 #define LTDL_SYMBOL_LENGTH 128
80 #undef LTDL_SYMBOL_OVERHEAD
81 /* This accounts for the _LTX_ separator */
82 #define LTDL_SYMBOL_OVERHEAD 5
84 static const char objdir[] = LTDL_OBJDIR;
86 static const char shlib_ext[] = LTDL_SHLIB_EXT;
89 static const char unknown_error[] = "unknown error";
90 static const char dlopen_not_supported_error[] = "dlopen support not available";
91 static const char file_not_found_error[] = "file not found";
92 static const char no_symbols_error[] = "no symbols defined";
93 static const char cannot_open_error[] = "can't open the module";
94 static const char cannot_close_error[] = "can't close the module";
95 static const char symbol_error[] = "symbol not found";
96 static const char memory_error[] = "not enough memory";
97 static const char invalid_handle_error[] = "invalid handle";
98 static const char buffer_overflow_error[] = "internal buffer overflow";
99 static const char shutdown_error[] = "library already shutdown";
101 #ifndef HAVE_PRELOADED_SYMBOLS
102 /* If libtool won't define it, we'd better do */
103 const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
106 static const char *last_error = 0;
108 lt_ptr_t (*lt_dlmalloc) LTDL_PARAMS((size_t size)) = (lt_ptr_t(*)LTDL_PARAMS((size_t)))malloc;
109 void (*lt_dlfree) LTDL_PARAMS((lt_ptr_t ptr)) = (void(*)LTDL_PARAMS((lt_ptr_t)))free;
111 typedef struct lt_dltype_t {
112 struct lt_dltype_t *next;
113 const char *sym_prefix; /* prefix for symbols */
114 int (*mod_init) LTDL_PARAMS((void));
115 int (*mod_exit) LTDL_PARAMS((void));
116 int (*lib_open) LTDL_PARAMS((lt_dlhandle handle, const char *filename));
117 int (*lib_close) LTDL_PARAMS((lt_dlhandle handle));
118 lt_ptr_t (*find_sym) LTDL_PARAMS((lt_dlhandle handle, const char *symbol));
121 #define LTDL_TYPE_TOP 0
123 typedef struct lt_dlhandle_t {
124 struct lt_dlhandle_t *next;
125 lt_dltype_t *type; /* dlopening interface */
126 char *filename; /* file name */
127 char *name; /* module name */
128 int usage; /* usage */
129 int depcount; /* number of dependencies */
130 lt_dlhandle *deplibs; /* dependencies */
131 lt_ptr_t handle; /* system handle */
132 lt_ptr_t system; /* system specific data */
136 #define strdup xstrdup
146 tmp = (char*) lt_dlmalloc(strlen(str)+1);
156 # define strchr index
160 # define strchr xstrchr
162 static inline const char*
169 for (p = str; *p != (char)ch && *p != '\0'; p++)
172 return (*p == (char)ch) ? p : 0;
183 # define strrchr rindex
187 # define strrchr xstrrchr
189 static inline const char*
196 for (p = str; *p != '\0'; p++)
199 while (*p != (char)ch && p >= str)
202 return (*p == (char)ch) ? p : 0;
211 /* dynamic linking with dlopen/dlsym */
218 # define LTDL_GLOBAL RTLD_GLOBAL
221 # define LTDL_GLOBAL DL_GLOBAL
223 # define LTDL_GLOBAL 0
227 /* We may have to define LTDL_LAZY_OR_NOW in the command line if we
228 find out it does not work in some platform. */
229 #ifndef LTDL_LAZY_OR_NOW
231 # define LTDL_LAZY_OR_NOW RTLD_LAZY
234 # define LTDL_LAZY_OR_NOW DL_LAZY
237 # define LTDL_LAZY_OR_NOW RTLD_NOW
240 # define LTDL_LAZY_OR_NOW DL_NOW
242 # define LTDL_LAZY_OR_NOW 0
250 sys_dl_init LTDL_PARAMS((void))
256 sys_dl_exit LTDL_PARAMS((void))
262 sys_dl_open (handle, filename)
264 const char *filename;
266 handle->handle = dlopen(filename, LTDL_GLOBAL | LTDL_LAZY_OR_NOW);
267 if (!handle->handle) {
269 last_error = dlerror();
271 last_error = cannot_open_error;
279 sys_dl_close (handle)
282 if (dlclose(handle->handle) != 0) {
284 last_error = dlerror();
286 last_error = cannot_close_error;
294 sys_dl_sym (handle, symbol)
298 lt_ptr_t address = dlsym(handle->handle, symbol);
302 last_error = dlerror();
304 last_error = symbol_error;
312 sys_dl = { LTDL_TYPE_TOP, "_", sys_dl_init, sys_dl_exit,
313 sys_dl_open, sys_dl_close, sys_dl_sym };
315 sys_dl = { LTDL_TYPE_TOP, 0, sys_dl_init, sys_dl_exit,
316 sys_dl_open, sys_dl_close, sys_dl_sym };
320 #define LTDL_TYPE_TOP &sys_dl
326 /* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
332 /* some flags are missing on some systems, so we provide
336 * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
337 * BIND_DEFERRED - Delay code symbol resolution until actual reference.
340 * BIND_FIRST - Place the library at the head of the symbol search order.
341 * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all unsatisfied
342 * symbols as fatal. This flag allows binding of unsatisfied code
343 * symbols to be deferred until use.
344 * [Perl: For certain libraries, like DCE, deferred binding often
345 * causes run time problems. Adding BIND_NONFATAL to BIND_IMMEDIATE
346 * still allows unresolved references in situations like this.]
347 * BIND_NOSTART - Do not call the initializer for the shared library when the
348 * library is loaded, nor on a future call to shl_unload().
349 * BIND_VERBOSE - Print verbose messages concerning possible unsatisfied symbols.
351 * hp9000s700/hp9000s800:
352 * BIND_RESTRICTED - Restrict symbols visible by the library to those present at
354 * DYNAMIC_PATH - Allow the loader to dynamically search for the library specified
355 * by the path argument.
359 #define DYNAMIC_PATH 0
360 #endif /* DYNAMIC_PATH */
361 #ifndef BIND_RESTRICTED
362 #define BIND_RESTRICTED 0
363 #endif /* BIND_RESTRICTED */
365 #define LTDL_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
368 sys_shl_init LTDL_PARAMS((void))
374 sys_shl_exit LTDL_PARAMS((void))
380 sys_shl_open (handle, filename)
382 const char *filename;
384 handle->handle = shl_load(filename, LTDL_BIND_FLAGS, 0L);
385 if (!handle->handle) {
386 last_error = cannot_open_error;
393 sys_shl_close (handle)
396 if (shl_unload((shl_t) (handle->handle)) != 0) {
397 last_error = cannot_close_error;
404 sys_shl_sym (handle, symbol)
410 if (handle->handle && shl_findsym((shl_t*) &(handle->handle),
411 symbol, TYPE_UNDEFINED, &address) == 0)
414 last_error = symbol_error;
420 sys_shl = { LTDL_TYPE_TOP, 0, sys_shl_init, sys_shl_exit,
421 sys_shl_open, sys_shl_close, sys_shl_sym };
424 #define LTDL_TYPE_TOP &sys_shl
430 /* dynamic linking with dld */
437 sys_dld_init LTDL_PARAMS((void))
443 sys_dld_exit LTDL_PARAMS((void))
449 sys_dld_open (handle, filename)
451 const char *filename;
453 handle->handle = strdup(filename);
454 if (!handle->handle) {
455 last_error = memory_error;
458 if (dld_link(filename) != 0) {
459 last_error = cannot_open_error;
460 lt_dlfree(handle->handle);
467 sys_dld_close (handle)
470 if (dld_unlink_by_file((char*)(handle->handle), 1) != 0) {
471 last_error = cannot_close_error;
474 lt_dlfree(handle->filename);
479 sys_dld_sym (handle, symbol)
483 lt_ptr_t address = dld_get_func(symbol);
486 last_error = symbol_error;
492 sys_dld = { LTDL_TYPE_TOP, 0, sys_dld_init, sys_dld_exit,
493 sys_dld_open, sys_dld_close, sys_dld_sym };
496 #define LTDL_TYPE_TOP &sys_dld
502 /* dynamic linking for Win32 */
507 sys_wll_init LTDL_PARAMS((void))
513 sys_wll_exit LTDL_PARAMS((void))
518 /* Forward declaration; required to implement handle search below. */
519 static lt_dlhandle handles;
522 sys_wll_open (handle, filename)
524 const char *filename;
527 char *searchname = NULL;
528 char *ext = strrchr(filename, '.');
531 /* FILENAME already has an extension. */
532 searchname = strdup(filename);
534 /* Append a `.' to stop Windows from adding an
535 implicit `.dll' extension. */
536 searchname = (char*)lt_dlmalloc(2+ strlen(filename));
537 strcpy(searchname, filename);
538 strcat(searchname, ".");
541 handle->handle = LoadLibrary(searchname);
542 lt_dlfree(searchname);
544 /* libltdl expects this function to fail if it is unable
545 to physically load the library. Sadly, LoadLibrary
546 will search the loaded libraries for a match and return
547 one of them if the path search load fails.
549 We check whether LoadLibrary is returning a handle to
550 an already loaded module, and simulate failure if we
558 if (cur->handle == handle->handle)
563 if (cur || !handle->handle) {
564 last_error = cannot_open_error;
572 sys_wll_close (handle)
575 if (FreeLibrary(handle->handle) == 0) {
576 last_error = cannot_close_error;
583 sys_wll_sym (handle, symbol)
587 lt_ptr_t address = GetProcAddress(handle->handle, symbol);
590 last_error = symbol_error;
596 sys_wll = { LTDL_TYPE_TOP, 0, sys_wll_init, sys_wll_exit,
597 sys_wll_open, sys_wll_close, sys_wll_sym };
600 #define LTDL_TYPE_TOP &sys_wll
606 /* dynamic linking for BeOS */
608 #include <kernel/image.h>
611 sys_bedl_init LTDL_PARAMS((void))
617 sys_bedl_exit LTDL_PARAMS((void))
623 sys_bedl_open (handle, filename)
625 const char *filename;
630 image = load_add_on(filename);
634 if (get_next_image_info(0, &cookie, &info) == B_OK)
635 image = load_add_on(info.name);
638 last_error = cannot_open_error;
641 handle->handle = (void*) image;
646 sys_bedl_close (handle)
649 if (unload_add_on((image_id)handle->handle) != B_OK) {
650 last_error = cannot_close_error;
657 sys_bedl_sym (handle, symbol)
661 lt_ptr_t address = 0;
662 image_id image = (image_id)handle->handle;
664 if (get_image_symbol(image, symbol, B_SYMBOL_TYPE_ANY,
666 last_error = symbol_error;
674 sys_bedl = { LTDL_TYPE_TOP, 0, sys_bedl_init, sys_bedl_exit,
675 sys_bedl_open, sys_bedl_close, sys_bedl_sym };
678 #define LTDL_TYPE_TOP &sys_bedl
682 /* emulate dynamic linking using preloaded_symbols */
684 typedef struct lt_dlsymlists_t {
685 struct lt_dlsymlists_t *next;
686 const lt_dlsymlist *syms;
689 static const lt_dlsymlist *default_preloaded_symbols = 0;
690 static lt_dlsymlists_t *preloaded_symbols = 0;
693 presym_init LTDL_PARAMS((void))
695 preloaded_symbols = 0;
696 if (default_preloaded_symbols)
697 return lt_dlpreload(default_preloaded_symbols);
702 presym_free_symlists LTDL_PARAMS((void))
704 lt_dlsymlists_t *lists = preloaded_symbols;
707 lt_dlsymlists_t *tmp = lists;
712 preloaded_symbols = 0;
717 presym_exit LTDL_PARAMS((void))
719 presym_free_symlists();
724 presym_add_symlist (preloaded)
725 const lt_dlsymlist *preloaded;
727 lt_dlsymlists_t *tmp;
728 lt_dlsymlists_t *lists = preloaded_symbols;
731 if (lists->syms == preloaded)
736 tmp = (lt_dlsymlists_t*) lt_dlmalloc(sizeof(lt_dlsymlists_t));
738 last_error = memory_error;
741 tmp->syms = preloaded;
743 if (!preloaded_symbols)
744 preloaded_symbols = tmp;
746 /* append to the end */
747 lists = preloaded_symbols;
756 presym_open (handle, filename)
758 const char *filename;
760 lt_dlsymlists_t *lists = preloaded_symbols;
763 last_error = no_symbols_error;
767 filename = "@PROGRAM@";
769 const lt_dlsymlist *syms = lists->syms;
772 if (!syms->address &&
773 strcmp(syms->name, filename) == 0) {
774 handle->handle = (lt_ptr_t) syms;
781 last_error = file_not_found_error;
786 presym_close (handle)
789 /* Just to silence gcc -Wall */
795 presym_sym (handle, symbol)
799 lt_dlsymlist *syms = (lt_dlsymlist*)(handle->handle);
802 while (syms->address) {
803 if (strcmp(syms->name, symbol) == 0)
804 return syms->address;
807 last_error = symbol_error;
813 presym = { LTDL_TYPE_TOP, 0, presym_init, presym_exit,
814 presym_open, presym_close, presym_sym };
817 #define LTDL_TYPE_TOP &presym
819 static char *user_search_path = 0;
820 static lt_dlhandle handles = 0;
821 static int initialized = 0;
823 static lt_dltype_t *types = LTDL_TYPE_TOP;
827 lt_dlinit LTDL_PARAMS((void))
829 /* initialize libltdl */
830 lt_dltype_t **type = &types;
833 if (initialized) { /* Initialize only at first call. */
838 user_search_path = 0; /* empty search path */
841 if ((*type)->mod_init())
842 *type = (*type)->next; /* Remove it from the list */
844 type = &(*type)->next; /* Keep it */
848 if (typecount == 0) {
849 last_error = dlopen_not_supported_error;
858 lt_dlpreload (preloaded)
859 const lt_dlsymlist *preloaded;
862 return presym_add_symlist(preloaded);
863 presym_free_symlists();
864 if (default_preloaded_symbols)
865 return lt_dlpreload(default_preloaded_symbols);
870 lt_dlpreload_default (preloaded)
871 const lt_dlsymlist *preloaded;
873 default_preloaded_symbols = preloaded;
878 lt_dlexit LTDL_PARAMS((void))
880 /* shut down libltdl */
881 lt_dltype_t *type = types;
885 last_error = shutdown_error;
888 if (initialized != 1) { /* shut down only at last call. */
892 /* close all modules */
895 /* FIXME: what if a module depends on another one? */
896 if (lt_dlclose(handles))
901 if (type->mod_exit())
909 tryall_dlopen (handle, filename)
911 const char *filename;
914 lt_dltype_t *type = types;
915 const char *saved_error = last_error;
917 /* check whether the module was already opened */
920 if (!cur->filename && !filename)
922 if (cur->filename && filename &&
923 strcmp(cur->filename, filename) == 0)
935 cur->filename = strdup(filename);
936 if (!cur->filename) {
937 last_error = memory_error;
943 if (type->lib_open(cur, filename) == 0)
949 lt_dlfree(cur->filename);
953 last_error = saved_error;
958 find_module (handle, dir, libdir, dlname, old_name, installed)
963 const char *old_name;
968 /* try to open the old library first; if it was dlpreopened,
969 we want the preopened version of it, even if a dlopenable
970 module is available */
971 if (old_name && tryall_dlopen(handle, old_name) == 0)
973 /* try to open the dynamic library */
975 /* try to open the installed module */
976 if (installed && libdir) {
978 lt_dlmalloc(strlen(libdir)+1+strlen(dlname)+1);
980 last_error = memory_error;
983 strcpy(filename, libdir);
984 strcat(filename, "/");
985 strcat(filename, dlname);
986 error = tryall_dlopen(handle, filename) == 0;
991 /* try to open the not-installed module */
994 lt_dlmalloc((dir ? strlen(dir) : 0)
995 + strlen(objdir) + strlen(dlname) + 1);
997 last_error = memory_error;
1001 strcpy(filename, dir);
1004 strcat(filename, objdir);
1005 strcat(filename, dlname);
1007 error = tryall_dlopen(handle, filename) == 0;
1008 lt_dlfree(filename);
1012 /* hmm, maybe it was moved to another directory */
1015 lt_dlmalloc((dir ? strlen(dir) : 0)
1016 + strlen(dlname) + 1);
1018 strcpy(filename, dir);
1021 strcat(filename, dlname);
1022 error = tryall_dlopen(handle, filename) == 0;
1023 lt_dlfree(filename);
1028 last_error = file_not_found_error;
1033 find_file (basename, search_path, pdir, handle)
1034 const char *basename;
1035 const char *search_path;
1037 lt_dlhandle *handle;
1039 /* when handle != NULL search a library, otherwise a file */
1040 /* return NULL on failure, otherwise the file/handle */
1043 int filenamesize = 0;
1044 const char *next = search_path;
1045 int lenbase = strlen(basename);
1047 if (!next || !*next) {
1048 last_error = file_not_found_error;
1053 const char *cur = next;
1055 next = strchr(cur, ':');
1057 next = cur + strlen(cur);
1058 lendir = next - cur;
1065 if (lendir + 1 + lenbase >= filenamesize) {
1067 lt_dlfree(filename);
1068 filenamesize = lendir + 1 + lenbase + 1;
1069 filename = (char*) lt_dlmalloc(filenamesize);
1071 last_error = memory_error;
1075 strncpy(filename, cur, lendir);
1076 if (filename[lendir-1] != '/')
1077 filename[lendir++] = '/';
1078 strcpy(filename+lendir, basename);
1080 if (tryall_dlopen(handle, filename) == 0) {
1081 lt_dlfree(filename);
1082 return (lt_ptr_t) handle;
1085 FILE *file = fopen(filename, LTDL_READTEXT_MODE);
1089 filename[lendir] = '\0';
1090 *pdir = strdup(filename);
1092 /* We could have even avoided the
1093 strdup, but there would be some
1097 lt_dlfree(filename);
1098 return (lt_ptr_t) file;
1103 lt_dlfree(filename);
1104 last_error = file_not_found_error;
1109 load_deplibs(handle, deplibs)
1111 const char *deplibs;
1113 /* FIXME: load deplibs */
1114 handle->depcount = 0;
1115 handle->deplibs = 0;
1116 /* Just to silence gcc -Wall */
1122 unload_deplibs(handle)
1125 /* FIXME: unload deplibs */
1126 /* Just to silence gcc -Wall */
1136 /* remove the leading and trailing "'" from str
1137 and store the result in dest */
1139 const char *end = strrchr(str, '\'');
1140 int len = strlen(str);
1144 if (len > 3 && str[0] == '\'') {
1145 tmp = (char*) lt_dlmalloc(end - str);
1147 last_error = memory_error;
1150 strncpy(tmp, &str[1], (end - str) - 1);
1159 free_vars(dir, name, dlname, oldname, libdir, deplibs)
1183 lt_dlopen (filename)
1184 const char *filename;
1186 lt_dlhandle handle, newhandle;
1187 const char *basename, *ext;
1188 const char *saved_error = last_error;
1189 char *dir = 0, *name = 0;
1192 handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
1194 last_error = memory_error;
1198 handle->depcount = 0;
1199 handle->deplibs = 0;
1201 if (tryall_dlopen(&newhandle, 0) != 0) {
1205 goto register_handle;
1207 basename = strrchr(filename, '/');
1210 dir = (char*) lt_dlmalloc(basename - filename + 1);
1212 last_error = memory_error;
1215 strncpy(dir, filename, basename - filename);
1216 dir[basename - filename] = '\0';
1218 basename = filename;
1219 /* check whether we open a libtool module (.la extension) */
1220 ext = strrchr(basename, '.');
1221 if (ext && strcmp(ext, ".la") == 0) {
1222 /* this seems to be a libtool module */
1225 char *dlname = 0, *old_name = 0;
1226 char *libdir = 0, *deplibs = 0;
1229 /* if we can't find the installed flag, it is probably an
1230 installed libtool archive, produced with an old version
1234 /* extract the module name from the file name */
1235 name = (char*) lt_dlmalloc(ext - basename + 1);
1237 last_error = memory_error;
1242 /* canonicalize the module name */
1243 for (i = 0; i < ext - basename; i++)
1244 if (isalnum((int)(basename[i])))
1245 name[i] = basename[i];
1248 name[ext - basename] = '\0';
1249 /* now try to open the .la file */
1250 file = fopen(filename, LTDL_READTEXT_MODE);
1252 last_error = file_not_found_error;
1253 if (!file && !dir) {
1254 /* try other directories */
1255 file = (FILE*) find_file(basename,
1259 file = (FILE*) find_file(basename,
1260 getenv("LTDL_LIBRARY_PATH"),
1262 #ifdef LTDL_SHLIBPATH_VAR
1264 file = (FILE*) find_file(basename,
1265 getenv(LTDL_SHLIBPATH_VAR),
1276 line = (char*) lt_dlmalloc(LTDL_FILENAME_MAX);
1279 last_error = memory_error;
1282 /* read the .la file */
1283 while (!feof(file)) {
1284 if (!fgets(line, LTDL_FILENAME_MAX, file))
1286 if (line[0] == '\n' || line[0] == '#')
1289 # define STR_DLNAME "dlname="
1290 if (strncmp(line, STR_DLNAME,
1291 sizeof(STR_DLNAME) - 1) == 0)
1292 error = trim(&dlname,
1293 &line[sizeof(STR_DLNAME) - 1]);
1295 # undef STR_OLD_LIBRARY
1296 # define STR_OLD_LIBRARY "old_library="
1297 if (strncmp(line, STR_OLD_LIBRARY,
1298 sizeof(STR_OLD_LIBRARY) - 1) == 0)
1299 error = trim(&old_name,
1300 &line[sizeof(STR_OLD_LIBRARY) - 1]);
1303 # define STR_LIBDIR "libdir="
1304 if (strncmp(line, STR_LIBDIR,
1305 sizeof(STR_LIBDIR) - 1) == 0)
1306 error = trim(&libdir,
1307 &line[sizeof(STR_LIBDIR) - 1]);
1309 # undef STR_DL_DEPLIBS
1310 # define STR_DL_DEPLIBS "dl_dependency_libs="
1311 if (strncmp(line, STR_DL_DEPLIBS,
1312 sizeof(STR_DL_DEPLIBS) - 1) == 0)
1313 error = trim(&deplibs,
1314 &line[sizeof(STR_DL_DEPLIBS) - 1]);
1316 if (strcmp(line, "installed=yes\n") == 0)
1319 if (strcmp(line, "installed=no\n") == 0)
1326 /* allocate the handle */
1327 handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
1328 if (!handle || error) {
1332 last_error = memory_error;
1333 free_vars(name, dir, dlname, old_name, libdir, deplibs);
1337 if (load_deplibs(handle, deplibs) == 0) {
1339 /* find_module may replace newhandle */
1340 if (find_module(&newhandle, dir, libdir,
1341 dlname, old_name, installed)) {
1342 unload_deplibs(handle);
1349 free_vars(name, dir, dlname, old_name, libdir, deplibs);
1352 free_vars(NULL, NULL, dlname, old_name, libdir, deplibs);
1353 if (handle != newhandle) {
1354 unload_deplibs(handle);
1357 /* not a libtool module */
1358 handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
1360 last_error = memory_error;
1366 /* non-libtool modules don't have dependencies */
1367 handle->depcount = 0;
1368 handle->deplibs = 0;
1370 if (tryall_dlopen(&newhandle, filename)
1372 || (!find_file(basename, user_search_path,
1374 && !find_file(basename,
1375 getenv("LTDL_LIBRARY_PATH"),
1377 #ifdef LTDL_SHLIBPATH_VAR
1378 && !find_file(basename,
1379 getenv(LTDL_SHLIBPATH_VAR),
1390 if (newhandle != handle) {
1394 if (!handle->usage) {
1396 handle->name = name;
1397 handle->next = handles;
1403 last_error = saved_error;
1408 lt_dlopenext (filename)
1409 const char *filename;
1414 const char *saved_error = last_error;
1417 return lt_dlopen(filename);
1418 len = strlen(filename);
1420 last_error = file_not_found_error;
1423 /* try the normal file name */
1424 handle = lt_dlopen(filename);
1427 /* try "filename.la" */
1428 tmp = (char*) lt_dlmalloc(len+4);
1430 last_error = memory_error;
1433 strcpy(tmp, filename);
1435 handle = lt_dlopen(tmp);
1437 last_error = saved_error;
1441 #ifdef LTDL_SHLIB_EXT
1442 /* try "filename.EXT" */
1443 if (strlen(shlib_ext) > 3) {
1445 tmp = (char*) lt_dlmalloc(len + strlen(shlib_ext) + 1);
1447 last_error = memory_error;
1450 strcpy(tmp, filename);
1453 strcat(tmp, shlib_ext);
1454 handle = lt_dlopen(tmp);
1456 last_error = saved_error;
1462 * WTF? It's SUPPOSED to look for statically linked libraries,
1463 * but the bugger doesn't!
1465 strcpy(tmp, filename);
1467 handle = lt_dlopen(tmp);
1469 last_error = saved_error;
1473 last_error = file_not_found_error;
1482 lt_dlhandle cur, last;
1484 /* check whether the handle is valid */
1485 last = cur = handles;
1486 while (cur && handle != cur) {
1491 last_error = invalid_handle_error;
1495 if (!handle->usage) {
1498 if (handle != handles)
1499 last->next = handle->next;
1501 handles = handle->next;
1502 error = handle->type->lib_close(handle);
1503 error += unload_deplibs(handle);
1504 if (handle->filename)
1505 lt_dlfree(handle->filename);
1507 lt_dlfree(handle->name);
1515 lt_dlsym (handle, symbol)
1520 char lsym[LTDL_SYMBOL_LENGTH];
1525 last_error = invalid_handle_error;
1529 last_error = symbol_error;
1532 lensym = strlen(symbol);
1533 if (handle->type->sym_prefix)
1534 lensym += strlen(handle->type->sym_prefix);
1536 lensym += strlen(handle->name);
1537 if (lensym + LTDL_SYMBOL_OVERHEAD < LTDL_SYMBOL_LENGTH)
1540 sym = (char*) lt_dlmalloc(lensym + LTDL_SYMBOL_OVERHEAD + 1);
1542 last_error = buffer_overflow_error;
1546 const char *saved_error = last_error;
1548 /* this is a libtool module */
1549 if (handle->type->sym_prefix) {
1550 strcpy(sym, handle->type->sym_prefix);
1551 strcat(sym, handle->name);
1553 strcpy(sym, handle->name);
1554 strcat(sym, "_LTX_");
1555 strcat(sym, symbol);
1556 /* try "modulename_LTX_symbol" */
1557 address = handle->type->find_sym(handle, sym);
1563 last_error = saved_error;
1565 /* otherwise try "symbol" */
1566 if (handle->type->sym_prefix) {
1567 strcpy(sym, handle->type->sym_prefix);
1568 strcat(sym, symbol);
1570 strcpy(sym, symbol);
1571 address = handle->type->find_sym(handle, sym);
1578 lt_dlerror LTDL_PARAMS((void))
1580 const char *error = last_error;
1587 lt_dladdsearchdir (search_dir)
1588 const char *search_dir;
1590 if (!search_dir || !strlen(search_dir))
1592 if (!user_search_path) {
1593 user_search_path = strdup(search_dir);
1594 if (!user_search_path) {
1595 last_error = memory_error;
1599 char *new_search_path = (char*)
1600 lt_dlmalloc(strlen(user_search_path) +
1601 strlen(search_dir) + 2); /* ':' + '\0' == 2 */
1602 if (!new_search_path) {
1603 last_error = memory_error;
1606 strcpy(new_search_path, user_search_path);
1607 strcat(new_search_path, ":");
1608 strcat(new_search_path, search_dir);
1609 lt_dlfree(user_search_path);
1610 user_search_path = new_search_path;
1616 lt_dlsetsearchpath (search_path)
1617 const char *search_path;
1619 if (user_search_path)
1620 lt_dlfree(user_search_path);
1621 user_search_path = 0; /* reset the search path */
1622 if (!search_path || !strlen(search_path))
1624 user_search_path = strdup(search_path);
1625 if (!user_search_path)
1631 lt_dlgetsearchpath LTDL_PARAMS((void))
1633 return user_search_path;