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 if (handle != newhandle) {
1353 unload_deplibs(handle);
1356 /* not a libtool module */
1357 handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
1359 last_error = memory_error;
1365 /* non-libtool modules don't have dependencies */
1366 handle->depcount = 0;
1367 handle->deplibs = 0;
1369 if (tryall_dlopen(&newhandle, filename)
1371 || (!find_file(basename, user_search_path,
1373 && !find_file(basename,
1374 getenv("LTDL_LIBRARY_PATH"),
1376 #ifdef LTDL_SHLIBPATH_VAR
1377 && !find_file(basename,
1378 getenv(LTDL_SHLIBPATH_VAR),
1389 if (newhandle != handle) {
1393 if (!handle->usage) {
1395 handle->name = name;
1396 handle->next = handles;
1402 last_error = saved_error;
1407 lt_dlopenext (filename)
1408 const char *filename;
1413 const char *saved_error = last_error;
1416 return lt_dlopen(filename);
1417 len = strlen(filename);
1419 last_error = file_not_found_error;
1422 /* try the normal file name */
1423 handle = lt_dlopen(filename);
1426 /* try "filename.la" */
1427 tmp = (char*) lt_dlmalloc(len+4);
1429 last_error = memory_error;
1432 strcpy(tmp, filename);
1434 handle = lt_dlopen(tmp);
1436 last_error = saved_error;
1440 #ifdef LTDL_SHLIB_EXT
1441 /* try "filename.EXT" */
1442 if (strlen(shlib_ext) > 3) {
1444 tmp = (char*) lt_dlmalloc(len + strlen(shlib_ext) + 1);
1446 last_error = memory_error;
1449 strcpy(tmp, filename);
1452 strcat(tmp, shlib_ext);
1453 handle = lt_dlopen(tmp);
1455 last_error = saved_error;
1460 last_error = file_not_found_error;
1469 lt_dlhandle cur, last;
1471 /* check whether the handle is valid */
1472 last = cur = handles;
1473 while (cur && handle != cur) {
1478 last_error = invalid_handle_error;
1482 if (!handle->usage) {
1485 if (handle != handles)
1486 last->next = handle->next;
1488 handles = handle->next;
1489 error = handle->type->lib_close(handle);
1490 error += unload_deplibs(handle);
1491 if (handle->filename)
1492 lt_dlfree(handle->filename);
1494 lt_dlfree(handle->name);
1502 lt_dlsym (handle, symbol)
1507 char lsym[LTDL_SYMBOL_LENGTH];
1512 last_error = invalid_handle_error;
1516 last_error = symbol_error;
1519 lensym = strlen(symbol);
1520 if (handle->type->sym_prefix)
1521 lensym += strlen(handle->type->sym_prefix);
1523 lensym += strlen(handle->name);
1524 if (lensym + LTDL_SYMBOL_OVERHEAD < LTDL_SYMBOL_LENGTH)
1527 sym = (char*) lt_dlmalloc(lensym + LTDL_SYMBOL_OVERHEAD + 1);
1529 last_error = buffer_overflow_error;
1533 const char *saved_error = last_error;
1535 /* this is a libtool module */
1536 if (handle->type->sym_prefix) {
1537 strcpy(sym, handle->type->sym_prefix);
1538 strcat(sym, handle->name);
1540 strcpy(sym, handle->name);
1541 strcat(sym, "_LTX_");
1542 strcat(sym, symbol);
1543 /* try "modulename_LTX_symbol" */
1544 address = handle->type->find_sym(handle, sym);
1550 last_error = saved_error;
1552 /* otherwise try "symbol" */
1553 if (handle->type->sym_prefix) {
1554 strcpy(sym, handle->type->sym_prefix);
1555 strcat(sym, symbol);
1557 strcpy(sym, symbol);
1558 address = handle->type->find_sym(handle, sym);
1565 lt_dlerror LTDL_PARAMS((void))
1567 const char *error = last_error;
1574 lt_dladdsearchdir (search_dir)
1575 const char *search_dir;
1577 if (!search_dir || !strlen(search_dir))
1579 if (!user_search_path) {
1580 user_search_path = strdup(search_dir);
1581 if (!user_search_path) {
1582 last_error = memory_error;
1586 char *new_search_path = (char*)
1587 lt_dlmalloc(strlen(user_search_path) +
1588 strlen(search_dir) + 2); /* ':' + '\0' == 2 */
1589 if (!new_search_path) {
1590 last_error = memory_error;
1593 strcpy(new_search_path, user_search_path);
1594 strcat(new_search_path, ":");
1595 strcat(new_search_path, search_dir);
1596 lt_dlfree(user_search_path);
1597 user_search_path = new_search_path;
1603 lt_dlsetsearchpath (search_path)
1604 const char *search_path;
1606 if (user_search_path)
1607 lt_dlfree(user_search_path);
1608 user_search_path = 0; /* reset the search path */
1609 if (!search_path || !strlen(search_path))
1611 user_search_path = strdup(search_path);
1612 if (!user_search_path)
1618 lt_dlgetsearchpath LTDL_PARAMS((void))
1620 return user_search_path;