1 /* ltdl.c -- system independent dlopen wrapper
2 Copyright (C) 1998, 1999, 2000 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 Lesser 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 Lesser General Public License,
12 if you distribute this file as part of a program or library that
13 is built using GNU libtool, 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 Lesser General Public License for more details.
21 You should have received a copy of the GNU Lesser 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
28 #define _LTDL_COMPILE_
69 # define LTDL_GLOBAL_DATA __declspec(dllexport)
71 # define LTDL_GLOBAL_DATA
74 /* max. filename length */
75 #ifndef LTDL_FILENAME_MAX
76 #define LTDL_FILENAME_MAX 1024
79 #undef LTDL_READTEXT_MODE
80 /* fopen() mode flags for reading a text file */
82 #define LTDL_READTEXT_MODE "rt"
84 #define LTDL_READTEXT_MODE "r"
87 #undef LTDL_SYMBOL_LENGTH
88 /* This is the maximum symbol size that won't require malloc/free */
89 #define LTDL_SYMBOL_LENGTH 128
91 #undef LTDL_SYMBOL_OVERHEAD
92 /* This accounts for the _LTX_ separator */
93 #define LTDL_SYMBOL_OVERHEAD 5
95 /* NOTE: typedefed in ltdl.h
96 This structure is used for the list of registered loaders. */
97 struct lt_dlloader_t
{
98 struct lt_dlloader_t
*next
;
99 const char *loader_name
; /* identifying name for each loader */
100 const char *sym_prefix
; /* prefix for symbols */
101 lt_module_open_t
*module_open
;
102 lt_module_close_t
*module_close
;
103 lt_find_sym_t
*find_sym
;
104 lt_dlloader_exit_t
*dlloader_exit
;
105 lt_dlloader_data_t dlloader_data
;
108 typedef struct lt_dlhandle_t
{
109 struct lt_dlhandle_t
*next
;
110 lt_dlloader_t
*loader
; /* dlopening interface */
112 int depcount
; /* number of dependencies */
113 lt_dlhandle
*deplibs
; /* dependencies */
114 lt_module_t module
; /* system module handle */
115 lt_ptr_t system
; /* system specific data */
116 lt_ptr_t app_private
; /* application private data */
119 static const char objdir
[] = LTDL_OBJDIR
;
120 #ifdef LTDL_SHLIB_EXT
121 static const char shlib_ext
[] = LTDL_SHLIB_EXT
;
123 #ifdef LTDL_SYSSEARCHPATH
124 static const char sys_search_path
[] = LTDL_SYSSEARCHPATH
;
127 /* Extract the diagnostic strings from the error table macro in the same
128 order as the enumberated indices in ltdl.h. */
129 #define LTDL_ERROR(name, diagnostic) (diagnostic),
130 static const char *ltdl_error_strings
[] = {
137 # define LT_DLSTRERROR(name) ltdl_error_strings[LTDL_ERROR_##name]
139 # define LT_DLSTRERROR(name) ltdl_error_strings[LTDL_ERROR_/**/name]
142 static const char *last_error
= 0;
144 LTDL_GLOBAL_DATA
lt_ptr_t (*lt_dlmalloc
) LTDL_PARAMS((size_t size
)) = (lt_ptr_t(*)LTDL_PARAMS((size_t)))malloc
;
145 LTDL_GLOBAL_DATA
void (*lt_dlfree
) LTDL_PARAMS((lt_ptr_t ptr
)) = (void(*)LTDL_PARAMS((lt_ptr_t
)))free
;
148 #define strdup xstrdup
158 tmp
= (char*) lt_dlmalloc(strlen(str
)+1);
167 #define strcmp xstrcmp
181 for (;*str1
&& *str2
; str1
++, str2
++)
185 return (int)(*str1
- *str2
);
194 # define strchr index
198 # define strchr xstrchr
200 static inline const char*
207 for (p
= str
; *p
!= (char)ch
&& *p
!= '\0'; p
++)
210 return (*p
== (char)ch
) ? p
: 0;
221 # define strrchr rindex
225 # define strrchr xstrrchr
227 static inline const char*
234 for (p
= str
; *p
!= '\0'; p
++)
237 while (*p
!= (char)ch
&& p
>= str
)
240 return (*p
== (char)ch
) ? p
: 0;
247 /* The Cygwin dlopen implementation prints a spurious error message to
248 stderr if its call to LoadLibrary() fails for any reason. We can
249 mitigate this by not using the Cygwin implementation, and falling
250 back to our own LoadLibrary() wrapper. */
251 #if HAVE_LIBDL && !defined(__CYGWIN__)
253 /* dynamic linking with dlopen/dlsym */
260 # define LTDL_GLOBAL RTLD_GLOBAL
263 # define LTDL_GLOBAL DL_GLOBAL
265 # define LTDL_GLOBAL 0
269 /* We may have to define LTDL_LAZY_OR_NOW in the command line if we
270 find out it does not work in some platform. */
271 #ifndef LTDL_LAZY_OR_NOW
273 # define LTDL_LAZY_OR_NOW RTLD_LAZY
276 # define LTDL_LAZY_OR_NOW DL_LAZY
279 # define LTDL_LAZY_OR_NOW RTLD_NOW
282 # define LTDL_LAZY_OR_NOW DL_NOW
284 # define LTDL_LAZY_OR_NOW 0
292 sys_dl_open (loader_data
, filename
)
293 lt_dlloader_data_t loader_data
;
294 const char *filename
;
296 lt_module_t module
= dlopen(filename
, LTDL_GLOBAL
| LTDL_LAZY_OR_NOW
);
299 last_error
= dlerror();
301 last_error
= LT_DLSTRERROR(CANNOT_OPEN
);
308 sys_dl_close (loader_data
, module
)
309 lt_dlloader_data_t loader_data
;
312 if (dlclose(module
) != 0) {
314 last_error
= dlerror();
316 last_error
= LT_DLSTRERROR(CANNOT_CLOSE
);
324 sys_dl_sym (loader_data
, module
, symbol
)
325 lt_dlloader_data_t loader_data
;
329 lt_ptr_t address
= dlsym(module
, symbol
);
333 last_error
= dlerror();
335 last_error
= LT_DLSTRERROR(SYMBOL_NOT_FOUND
);
340 static struct lt_user_dlloader sys_dl
= {
346 sys_dl_open
, sys_dl_close
, sys_dl_sym
, 0, 0 };
351 /* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
357 /* some flags are missing on some systems, so we provide
361 * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
362 * BIND_DEFERRED - Delay code symbol resolution until actual reference.
365 * BIND_FIRST - Place the library at the head of the symbol search order.
366 * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all unsatisfied
367 * symbols as fatal. This flag allows binding of unsatisfied code
368 * symbols to be deferred until use.
369 * [Perl: For certain libraries, like DCE, deferred binding often
370 * causes run time problems. Adding BIND_NONFATAL to BIND_IMMEDIATE
371 * still allows unresolved references in situations like this.]
372 * BIND_NOSTART - Do not call the initializer for the shared library when the
373 * library is loaded, nor on a future call to shl_unload().
374 * BIND_VERBOSE - Print verbose messages concerning possible unsatisfied symbols.
376 * hp9000s700/hp9000s800:
377 * BIND_RESTRICTED - Restrict symbols visible by the library to those present at
379 * DYNAMIC_PATH - Allow the loader to dynamically search for the library specified
380 * by the path argument.
384 #define DYNAMIC_PATH 0
385 #endif /* DYNAMIC_PATH */
386 #ifndef BIND_RESTRICTED
387 #define BIND_RESTRICTED 0
388 #endif /* BIND_RESTRICTED */
390 #define LTDL_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
393 sys_shl_open (loader_data
, filename
)
394 lt_dlloader_data_t loader_data
;
395 const char *filename
;
397 lt_module_t module
= shl_load(filename
, LTDL_BIND_FLAGS
, 0L);
399 last_error
= LT_DLSTRERROR(CANNOT_OPEN
);
405 sys_shl_close (loader_data
, module
)
406 lt_dlloader_data_t loader_data
;
409 if (shl_unload((shl_t
) (module
)) != 0) {
410 last_error
= LT_DLSTRERROR(CANNOT_CLOSE
);
417 sys_shl_sym (loader_data
, module
, symbol
)
418 lt_dlloader_data_t loader_data
;
424 if (module
&& shl_findsym((shl_t
*) &module
,
425 symbol
, TYPE_UNDEFINED
, &address
) == 0)
428 last_error
= LT_DLSTRERROR(SYMBOL_NOT_FOUND
);
432 static struct lt_user_dlloader
433 sys_shl
= { 0, sys_shl_open
, sys_shl_close
, sys_shl_sym
, 0, 0 };
436 #define LTDL_TYPE_TOP &sys_shl
442 /* dynamic linking for Win32 */
446 /* Forward declaration; required to implement handle search below. */
447 static lt_dlhandle handles
;
450 sys_wll_open (loader_data
, filename
)
451 lt_dlloader_data_t loader_data
;
452 const char *filename
;
456 char *searchname
= 0;
458 char self_name_buf
[MAX_PATH
];
461 /* Get the name of main module */
463 GetModuleFileName(NULL
, self_name_buf
, sizeof(self_name_buf
));
464 filename
= ext
= self_name_buf
;
466 else ext
= strrchr(filename
, '.');
469 /* FILENAME already has an extension. */
470 searchname
= strdup(filename
);
472 /* Append a `.' to stop Windows from adding an
473 implicit `.dll' extension. */
474 searchname
= (char*)lt_dlmalloc(2+ strlen(filename
));
476 last_error
= LT_DLSTRERROR(NO_MEMORY
);
479 strcpy(searchname
, filename
);
480 strcat(searchname
, ".");
483 module
= LoadLibrary(searchname
);
484 lt_dlfree(searchname
);
486 /* libltdl expects this function to fail if it is unable
487 to physically load the library. Sadly, LoadLibrary
488 will search the loaded libraries for a match and return
489 one of them if the path search load fails.
491 We check whether LoadLibrary is returning a handle to
492 an already loaded module, and simulate failure if we
500 if (cur
->module
== module
)
505 if (cur
|| !module
) {
506 last_error
= LT_DLSTRERROR(CANNOT_OPEN
);
514 sys_wll_close (loader_data
, module
)
515 lt_dlloader_data_t loader_data
;
518 if (FreeLibrary(module
) == 0) {
519 last_error
= LT_DLSTRERROR(CANNOT_CLOSE
);
526 sys_wll_sym (loader_data
, module
, symbol
)
527 lt_dlloader_data_t loader_data
;
531 lt_ptr_t address
= GetProcAddress(module
, symbol
);
534 last_error
= LT_DLSTRERROR(SYMBOL_NOT_FOUND
);
538 static struct lt_user_dlloader
539 sys_wll
= { 0, sys_wll_open
, sys_wll_close
, sys_wll_sym
, 0, 0 };
545 /* dynamic linking for BeOS */
547 #include <kernel/image.h>
550 sys_bedl_open (loader_data
, filename
)
551 lt_dlloader_data_t loader_data
;
552 const char *filename
;
557 image
= load_add_on(filename
);
561 if (get_next_image_info(0, &cookie
, &info
) == B_OK
)
562 image
= load_add_on(info
.name
);
565 last_error
= LT_DLSTRERROR(CANNOT_OPEN
);
569 return (lt_module_t
) image
;
573 sys_bedl_close (loader_data
, module
)
574 lt_dlloader_data_t loader_data
;
577 if (unload_add_on((image_id
)module
) != B_OK
) {
578 last_error
= LT_DLSTRERROR(CANNOT_CLOSE
);
585 sys_bedl_sym (loader_data
, module
, symbol
)
586 lt_dlloader_data_t loader_data
;
590 lt_ptr_t address
= 0;
591 image_id image
= (image_id
)module
;
593 if (get_image_symbol(image
, symbol
, B_SYMBOL_TYPE_ANY
,
595 last_error
= LT_DLSTRERROR(SYMBOL_NOT_FOUND
);
601 static struct lt_user_dlloader
602 sys_bedl
= { 0, sys_bedl_open
, sys_bedl_close
, sys_bedl_sym
, 0, 0 };
608 /* dynamic linking with dld */
615 sys_dld_open (loader_data
, filename
)
616 lt_dlloader_data_t loader_data
;
617 const char *filename
;
619 lt_module_t module
= strdup(filename
);
621 last_error
= LT_DLSTRERROR(NO_MEMORY
);
624 if (dld_link(filename
) != 0) {
625 last_error
= LT_DLSTRERROR(CANNOT_OPEN
);
633 sys_dld_close (loader_data
, module
)
634 lt_dlloader_data_t loader_data
;
637 if (dld_unlink_by_file((char*)(module
), 1) != 0) {
638 last_error
= LT_DLSTRERROR(CANNOT_CLOSE
);
646 sys_dld_sym (loader_data
, module
, symbol
)
647 lt_dlloader_data_t loader_data
;
651 lt_ptr_t address
= dld_get_func(symbol
);
654 last_error
= LT_DLSTRERROR(SYMBOL_NOT_FOUND
);
658 static struct lt_user_dlloader
659 sys_dld
= { 0, sys_dld_open
, sys_dld_close
, sys_dld_sym
, 0, 0 };
663 /* emulate dynamic linking using preloaded_symbols */
665 typedef struct lt_dlsymlists_t
{
666 struct lt_dlsymlists_t
*next
;
667 const lt_dlsymlist
*syms
;
670 static const lt_dlsymlist
*default_preloaded_symbols
= 0;
671 static lt_dlsymlists_t
*preloaded_symbols
= 0;
674 presym_init (loader_data
)
675 lt_dlloader_data_t loader_data
;
677 preloaded_symbols
= 0;
678 if (default_preloaded_symbols
)
679 return lt_dlpreload(default_preloaded_symbols
);
684 presym_free_symlists
LTDL_PARAMS((void))
686 lt_dlsymlists_t
*lists
= preloaded_symbols
;
689 lt_dlsymlists_t
*tmp
= lists
;
694 preloaded_symbols
= 0;
699 presym_exit (loader_data
)
700 lt_dlloader_data_t loader_data
;
702 presym_free_symlists();
707 presym_add_symlist (preloaded
)
708 const lt_dlsymlist
*preloaded
;
710 lt_dlsymlists_t
*tmp
;
711 lt_dlsymlists_t
*lists
= preloaded_symbols
;
714 if (lists
->syms
== preloaded
)
719 tmp
= (lt_dlsymlists_t
*) lt_dlmalloc(sizeof(lt_dlsymlists_t
));
721 last_error
= LT_DLSTRERROR(NO_MEMORY
);
724 tmp
->syms
= preloaded
;
725 tmp
->next
= preloaded_symbols
;
726 preloaded_symbols
= tmp
;
731 presym_open (loader_data
, filename
)
732 lt_dlloader_data_t loader_data
;
733 const char *filename
;
735 lt_dlsymlists_t
*lists
= preloaded_symbols
;
738 last_error
= LT_DLSTRERROR(NO_SYMBOLS
);
742 filename
= "@PROGRAM@";
744 const lt_dlsymlist
*syms
= lists
->syms
;
747 if (!syms
->address
&&
748 strcmp(syms
->name
, filename
) == 0) {
749 return (lt_module_t
) syms
;
755 last_error
= LT_DLSTRERROR(FILE_NOT_FOUND
);
760 presym_close (loader_data
, module
)
761 lt_dlloader_data_t loader_data
;
764 /* Just to silence gcc -Wall */
770 presym_sym (loader_data
, module
, symbol
)
771 lt_dlloader_data_t loader_data
;
775 lt_dlsymlist
*syms
= (lt_dlsymlist
*)(module
);
778 while (syms
->address
) {
779 if (strcmp(syms
->name
, symbol
) == 0)
780 return syms
->address
;
783 last_error
= LT_DLSTRERROR(SYMBOL_NOT_FOUND
);
787 static struct lt_user_dlloader
788 presym
= { 0, presym_open
, presym_close
, presym_sym
, presym_exit
, 0 };
791 static char *user_search_path
= 0;
792 static lt_dlloader_t
*loaders
= 0;
793 static lt_dlhandle handles
= 0;
794 static int initialized
= 0;
797 lt_dlinit
LTDL_PARAMS((void))
799 /* initialize libltdl */
802 if (initialized
) { /* Initialize only at first call. */
807 user_search_path
= 0; /* empty search path */
809 #if HAVE_LIBDL && !defined(__CYGWIN__)
810 errors
+= lt_dlloader_add (lt_dlloader_next(0), &sys_dl
, "dlopen");
813 errors
+= lt_dlloader_add (lt_dlloader_next(0), &sys_shl
, "dlopen");
816 errors
+= lt_dlloader_add (lt_dlloader_next(0), &sys_wll
, "dlopen");
819 errors
+= lt_dlloader_add (lt_dlloader_next(0), &sys_bedl
, "dlopen");
822 errors
+= lt_dlloader_add (lt_dlloader_next(0), &sys_dld
, "dld");
824 errors
+= lt_dlloader_add (lt_dlloader_next(0), &presym
, "dlpreload");
825 if (presym_init(presym
.dlloader_data
)) {
826 last_error
= LT_DLSTRERROR(INIT_LOADER
);
831 last_error
= LT_DLSTRERROR(DLOPEN_NOT_SUPPORTED
);
840 lt_dlpreload (preloaded
)
841 const lt_dlsymlist
*preloaded
;
844 return presym_add_symlist(preloaded
);
845 presym_free_symlists();
846 if (default_preloaded_symbols
)
847 return lt_dlpreload(default_preloaded_symbols
);
852 lt_dlpreload_default (preloaded
)
853 const lt_dlsymlist
*preloaded
;
855 default_preloaded_symbols
= preloaded
;
860 lt_dlexit
LTDL_PARAMS((void))
862 /* shut down libltdl */
863 lt_dlloader_t
*loader
= loaders
;
867 last_error
= LT_DLSTRERROR(SHUTDOWN
);
870 if (initialized
!= 1) { /* shut down only at last call. */
874 /* close all modules */
876 for (level
= 1; handles
; level
++) {
877 lt_dlhandle cur
= handles
;
879 lt_dlhandle tmp
= cur
;
881 if (tmp
->info
.ref_count
<= level
)
886 /* close all loaders */
888 lt_dlloader_t
*next
= loader
->next
;
889 lt_dlloader_data_t data
= loader
->dlloader_data
;
890 if (loader
->dlloader_exit
&& loader
->dlloader_exit(data
))
901 tryall_dlopen (handle
, filename
)
903 const char *filename
;
905 lt_dlhandle cur
= handles
;
906 lt_dlloader_t
*loader
= loaders
;
907 const char *saved_error
= last_error
;
909 /* check whether the module was already opened */
911 /* try to dlopen the program itself? */
912 if (!cur
->info
.filename
&& !filename
)
914 if (cur
->info
.filename
&& filename
&&
915 strcmp(cur
->info
.filename
, filename
) == 0)
921 cur
->info
.ref_count
++;
928 cur
->info
.filename
= strdup(filename
);
929 if (!cur
->info
.filename
) {
930 last_error
= LT_DLSTRERROR(NO_MEMORY
);
934 cur
->info
.filename
= 0;
936 lt_dlloader_data_t data
= loader
->dlloader_data
;
937 cur
->module
= loader
->module_open(data
, filename
);
938 if (cur
->module
!= 0)
940 loader
= loader
->next
;
943 if (cur
->info
.filename
)
944 lt_dlfree(cur
->info
.filename
);
947 cur
->loader
= loader
;
948 last_error
= saved_error
;
953 find_module (handle
, dir
, libdir
, dlname
, old_name
, installed
)
958 const char *old_name
;
963 /* try to open the old library first; if it was dlpreopened,
964 we want the preopened version of it, even if a dlopenable
965 module is available */
966 if (old_name
&& tryall_dlopen(handle
, old_name
) == 0)
968 /* try to open the dynamic library */
970 /* try to open the installed module */
971 if (installed
&& libdir
) {
973 lt_dlmalloc(strlen(libdir
)+1+strlen(dlname
)+1);
975 last_error
= LT_DLSTRERROR(NO_MEMORY
);
978 sprintf (filename
, "%s/%s", libdir
, dlname
);
979 error
= tryall_dlopen(handle
, filename
) != 0;
984 /* try to open the not-installed module */
987 lt_dlmalloc((dir
? strlen(dir
) : 0)
988 + strlen(objdir
) + strlen(dlname
) + 1);
990 last_error
= LT_DLSTRERROR(NO_MEMORY
);
994 strcpy(filename
, dir
);
997 strcat(filename
, objdir
);
998 strcat(filename
, dlname
);
1000 error
= tryall_dlopen(handle
, filename
) != 0;
1001 lt_dlfree(filename
);
1005 /* maybe it was moved to another directory */
1008 lt_dlmalloc((dir
? strlen(dir
) : 0)
1009 + strlen(dlname
) + 1);
1011 strcpy(filename
, dir
);
1014 strcat(filename
, dlname
);
1015 error
= tryall_dlopen(handle
, filename
) != 0;
1016 lt_dlfree(filename
);
1025 canonicalize_path (path
)
1028 char *canonical
= 0;
1030 if (path
&& *path
) {
1031 char *ptr
= strdup (path
);
1033 #ifdef LTDL_DIRSEP_CHAR
1034 /* Avoid this overhead where '/' is the only separator. */
1035 while (ptr
= strchr (ptr
, LTDL_DIRSEP_CHAR
))
1044 find_file (basename
, search_path
, pdir
, handle
)
1045 const char *basename
;
1046 const char *search_path
;
1048 lt_dlhandle
*handle
;
1050 /* when handle != NULL search a library, otherwise a file */
1051 /* return NULL on failure, otherwise the file/handle */
1053 lt_ptr_t result
= 0;
1055 int filenamesize
= 0;
1056 int lenbase
= strlen(basename
);
1057 char *canonical
= 0, *next
= 0;
1059 if (!search_path
|| !*search_path
) {
1060 last_error
= LT_DLSTRERROR(FILE_NOT_FOUND
);
1063 canonical
= canonicalize_path (search_path
);
1065 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1073 next
= strchr(cur
, LTDL_PATHSEP_CHAR
);
1075 next
= cur
+ strlen(cur
);
1076 lendir
= next
- cur
;
1077 if (*next
== LTDL_PATHSEP_CHAR
)
1083 if (lendir
+ 1 + lenbase
>= filenamesize
) {
1085 lt_dlfree(filename
);
1086 filenamesize
= lendir
+ 1 + lenbase
+ 1;
1087 filename
= (char*) lt_dlmalloc(filenamesize
);
1089 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1093 strncpy(filename
, cur
, lendir
);
1094 if (filename
[lendir
-1] != '/')
1095 filename
[lendir
++] = '/';
1096 strcpy(filename
+lendir
, basename
);
1098 if (tryall_dlopen(handle
, filename
) == 0) {
1099 result
= (lt_ptr_t
) handle
;
1103 FILE *file
= fopen(filename
, LTDL_READTEXT_MODE
);
1107 filename
[lendir
] = '\0';
1108 *pdir
= strdup(filename
);
1110 /* We could have even avoided the
1111 strdup, but there would be some
1116 result
= (lt_ptr_t
) file
;
1121 last_error
= LT_DLSTRERROR(FILE_NOT_FOUND
);
1124 lt_dlfree(filename
);
1126 lt_dlfree(canonical
);
1131 load_deplibs(handle
, deplibs
)
1135 char *p
, *save_search_path
;
1137 int ret
= 1, depcount
= 0;
1139 lt_dlhandle
*handles
= 0;
1141 handle
->depcount
= 0;
1144 save_search_path
= strdup(user_search_path
);
1145 if (user_search_path
&& !save_search_path
) {
1146 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1150 /* extract search paths and count deplibs */
1154 while (*end
&& !isspace(*end
)) end
++;
1155 if (strncmp(p
, "-L", 2) == 0 ||
1156 strncmp(p
, "-R", 2) == 0) {
1158 *end
= 0; /* set a temporary string terminator */
1159 if (lt_dladdsearchdir(p
+2))
1172 names
= (char**)lt_dlmalloc(depcount
* sizeof(char*));
1175 handles
= (lt_dlhandle
*)lt_dlmalloc(depcount
* sizeof(lt_dlhandle
*));
1179 /* now only extract the actual deplibs */
1184 while (*end
&& !isspace(*end
)) end
++;
1185 if (strncmp(p
, "-L", 2) != 0 &&
1186 strncmp(p
, "-R", 2) != 0) {
1189 *end
= 0; /* set a temporary string terminator */
1190 if (strncmp(p
, "-l", 2) == 0) {
1191 name
= lt_dlmalloc(3+ /* "lib" */
1194 sprintf (name
, "lib%s", p
+2);
1198 names
[depcount
++] = name
;
1207 /* load the deplibs (in reverse order) */
1208 for (i
= 0; i
< depcount
; i
++) {
1209 lt_dlhandle handle
= lt_dlopenext(names
[depcount
-1-i
]);
1212 for (j
= 0; j
< i
; j
++)
1213 lt_dlclose(handles
[j
]);
1214 last_error
= LT_DLSTRERROR(DEPLIB_NOT_FOUND
);
1217 handles
[i
] = handle
;
1219 handle
->depcount
= depcount
;
1220 handle
->deplibs
= handles
;
1224 for (i
= 0; i
< depcount
; i
++)
1225 lt_dlfree(names
[i
]);
1231 /* restore the old search path */
1232 if (user_search_path
)
1233 lt_dlfree(user_search_path
);
1234 user_search_path
= save_search_path
;
1239 unload_deplibs(handle
)
1245 if (!handle
->depcount
)
1247 for (i
= 0; i
< handle
->depcount
; i
++)
1248 errors
+= lt_dlclose(handle
->deplibs
[i
]);
1257 /* remove the leading and trailing "'" from str
1258 and store the result in dest */
1260 const char *end
= strrchr(str
, '\'');
1261 int len
= strlen(str
);
1265 if (len
> 3 && str
[0] == '\'') {
1266 tmp
= (char*) lt_dlmalloc(end
- str
);
1268 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1271 strncpy(tmp
, &str
[1], (end
- str
) - 1);
1280 free_vars( dlname
, oldname
, libdir
, deplibs
)
1298 lt_dlopen (filename
)
1299 const char *filename
;
1301 lt_dlhandle handle
= 0, newhandle
;
1303 const char *saved_error
= last_error
;
1304 char *canonical
= 0, *basename
= 0, *dir
= 0, *name
= 0;
1307 handle
= (lt_dlhandle
) lt_dlmalloc(sizeof(lt_dlhandle_t
));
1309 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1312 handle
->info
.ref_count
= 0;
1313 handle
->depcount
= 0;
1314 handle
->deplibs
= 0;
1316 if (tryall_dlopen(&newhandle
, 0) != 0) {
1320 goto register_handle
;
1322 canonical
= canonicalize_path (filename
);
1324 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1329 basename
= strrchr(canonical
, '/');
1332 dir
= (char*) lt_dlmalloc(basename
- canonical
+ 1);
1334 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1338 strncpy(dir
, canonical
, basename
- canonical
);
1339 dir
[basename
- canonical
] = '\0';
1341 basename
= canonical
;
1342 /* check whether we open a libtool module (.la extension) */
1343 ext
= strrchr(basename
, '.');
1344 if (ext
&& strcmp(ext
, ".la") == 0) {
1345 /* this seems to be a libtool module */
1348 char *dlname
= 0, *old_name
= 0;
1349 char *libdir
= 0, *deplibs
= 0;
1352 /* if we can't find the installed flag, it is probably an
1353 installed libtool archive, produced with an old version
1357 /* extract the module name from the file name */
1358 name
= (char*) lt_dlmalloc(ext
- basename
+ 1);
1360 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1364 /* canonicalize the module name */
1365 for (i
= 0; i
< ext
- basename
; i
++)
1366 if (isalnum((int)(basename
[i
])))
1367 name
[i
] = basename
[i
];
1370 name
[ext
- basename
] = '\0';
1371 /* now try to open the .la file */
1372 file
= fopen(filename
, LTDL_READTEXT_MODE
);
1374 last_error
= LT_DLSTRERROR(FILE_NOT_FOUND
);
1375 if (!file
&& !dir
) {
1376 /* try other directories */
1377 file
= (FILE*) find_file(basename
,
1381 file
= (FILE*) find_file(basename
,
1382 getenv("LTDL_LIBRARY_PATH"),
1384 #ifdef LTDL_SHLIBPATH_VAR
1386 file
= (FILE*) find_file(basename
,
1387 getenv(LTDL_SHLIBPATH_VAR
),
1390 #ifdef LTDL_SYSSEARCHPATH
1392 file
= (FILE*) find_file(basename
,
1401 line
= (char*) lt_dlmalloc(LTDL_FILENAME_MAX
);
1404 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1408 /* read the .la file */
1409 while (!feof(file
)) {
1410 if (!fgets(line
, LTDL_FILENAME_MAX
, file
))
1412 if (line
[0] == '\n' || line
[0] == '#')
1415 # define STR_DLNAME "dlname="
1416 if (strncmp(line
, STR_DLNAME
,
1417 sizeof(STR_DLNAME
) - 1) == 0)
1418 error
= trim(&dlname
,
1419 &line
[sizeof(STR_DLNAME
) - 1]);
1421 # undef STR_OLD_LIBRARY
1422 # define STR_OLD_LIBRARY "old_library="
1423 if (strncmp(line
, STR_OLD_LIBRARY
,
1424 sizeof(STR_OLD_LIBRARY
) - 1) == 0)
1425 error
= trim(&old_name
,
1426 &line
[sizeof(STR_OLD_LIBRARY
) - 1]);
1429 # define STR_LIBDIR "libdir="
1430 if (strncmp(line
, STR_LIBDIR
,
1431 sizeof(STR_LIBDIR
) - 1) == 0)
1432 error
= trim(&libdir
,
1433 &line
[sizeof(STR_LIBDIR
) - 1]);
1435 # undef STR_DL_DEPLIBS
1436 # define STR_DL_DEPLIBS "dl_dependency_libs="
1437 if (strncmp(line
, STR_DL_DEPLIBS
,
1438 sizeof(STR_DL_DEPLIBS
) - 1) == 0)
1439 error
= trim(&deplibs
,
1440 &line
[sizeof(STR_DL_DEPLIBS
) - 1]);
1442 if (strcmp(line
, "installed=yes\n") == 0)
1445 if (strcmp(line
, "installed=no\n") == 0)
1448 # undef STR_LIBRARY_NAMES
1449 # define STR_LIBRARY_NAMES "library_names="
1451 strncmp(line
, STR_LIBRARY_NAMES
,
1452 sizeof(STR_LIBRARY_NAMES
) - 1) == 0) {
1454 error
= trim(&dlname
,
1455 &line
[sizeof(STR_LIBRARY_NAMES
) - 1]);
1456 if (! error
&& dlname
&&
1457 (last_libname
= strrchr(dlname
, ' ')) != NULL
) {
1458 last_libname
= strdup(last_libname
+ 1);
1460 dlname
= last_libname
;
1468 /* allocate the handle */
1469 handle
= (lt_dlhandle
) lt_dlmalloc(sizeof(lt_dlhandle_t
));
1470 if (!handle
|| error
) {
1474 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1475 free_vars(dlname
, old_name
, libdir
, deplibs
);
1476 /* handle is already set to 0 */
1479 handle
->info
.ref_count
= 0;
1480 if (load_deplibs(handle
, deplibs
) == 0) {
1482 /* find_module may replace newhandle */
1483 if (find_module(&newhandle
, dir
, libdir
,
1484 dlname
, old_name
, installed
)) {
1485 unload_deplibs(handle
);
1490 free_vars(dlname
, old_name
, libdir
, deplibs
);
1496 if (handle
!= newhandle
)
1497 unload_deplibs(handle
);
1499 /* not a libtool module */
1500 handle
= (lt_dlhandle
) lt_dlmalloc(sizeof(lt_dlhandle_t
));
1502 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1503 /* handle is already set to 0 */
1506 handle
->info
.ref_count
= 0;
1507 /* non-libtool modules don't have dependencies */
1508 handle
->depcount
= 0;
1509 handle
->deplibs
= 0;
1511 if (tryall_dlopen(&newhandle
, filename
)
1513 || (!find_file(basename
, user_search_path
,
1515 && !find_file(basename
,
1516 getenv("LTDL_LIBRARY_PATH"),
1518 #ifdef LTDL_SHLIBPATH_VAR
1519 && !find_file(basename
,
1520 getenv(LTDL_SHLIBPATH_VAR
),
1523 #ifdef LTDL_SYSSEARCHPATH
1524 && !find_file(basename
, sys_search_path
,
1534 if (newhandle
!= handle
) {
1538 if (!handle
->info
.ref_count
) {
1539 handle
->info
.ref_count
= 1;
1540 handle
->info
.name
= name
;
1541 handle
->next
= handles
;
1543 name
= 0; /* don't free this during `cleanup' */
1545 last_error
= saved_error
;
1552 lt_dlfree(canonical
);
1557 lt_dlopenext (filename
)
1558 const char *filename
;
1563 const char *saved_error
= last_error
;
1566 return lt_dlopen(filename
);
1567 len
= strlen(filename
);
1569 last_error
= LT_DLSTRERROR(FILE_NOT_FOUND
);
1572 /* try the normal file name */
1573 handle
= lt_dlopen(filename
);
1576 /* try "filename.la" */
1577 tmp
= (char*) lt_dlmalloc(len
+4);
1579 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1582 strcpy(tmp
, filename
);
1584 handle
= lt_dlopen(tmp
);
1586 last_error
= saved_error
;
1590 #ifdef LTDL_SHLIB_EXT
1591 /* try "filename.EXT" */
1592 if (strlen(shlib_ext
) > 3) {
1594 tmp
= (char*) lt_dlmalloc(len
+ strlen(shlib_ext
) + 1);
1596 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1599 strcpy(tmp
, filename
);
1602 strcat(tmp
, shlib_ext
);
1603 handle
= lt_dlopen(tmp
);
1605 last_error
= saved_error
;
1610 last_error
= LT_DLSTRERROR(FILE_NOT_FOUND
);
1619 lt_dlhandle cur
, last
;
1621 /* check whether the handle is valid */
1622 last
= cur
= handles
;
1623 while (cur
&& handle
!= cur
) {
1628 last_error
= LT_DLSTRERROR(INVALID_HANDLE
);
1631 handle
->info
.ref_count
--;
1632 if (!handle
->info
.ref_count
) {
1634 lt_dlloader_data_t data
= handle
->loader
->dlloader_data
;
1636 if (handle
!= handles
)
1637 last
->next
= handle
->next
;
1639 handles
= handle
->next
;
1640 error
= handle
->loader
->module_close(data
, handle
->module
);
1641 error
+= unload_deplibs(handle
);
1642 if (handle
->info
.filename
)
1643 lt_dlfree(handle
->info
.filename
);
1644 if (handle
->info
.name
)
1645 lt_dlfree(handle
->info
.name
);
1653 lt_dlsym (handle
, symbol
)
1658 char lsym
[LTDL_SYMBOL_LENGTH
];
1661 lt_dlloader_data_t data
;
1664 last_error
= LT_DLSTRERROR(INVALID_HANDLE
);
1668 last_error
= LT_DLSTRERROR(SYMBOL_NOT_FOUND
);
1671 lensym
= strlen(symbol
);
1672 if (handle
->loader
->sym_prefix
)
1673 lensym
+= strlen(handle
->loader
->sym_prefix
);
1674 if (handle
->info
.name
)
1675 lensym
+= strlen(handle
->info
.name
);
1676 if (lensym
+ LTDL_SYMBOL_OVERHEAD
< LTDL_SYMBOL_LENGTH
)
1679 sym
= (char*) lt_dlmalloc(lensym
+ LTDL_SYMBOL_OVERHEAD
+ 1);
1681 last_error
= LT_DLSTRERROR(BUFFER_OVERFLOW
);
1684 data
= handle
->loader
->dlloader_data
;
1685 if (handle
->info
.name
) {
1686 const char *saved_error
= last_error
;
1688 /* this is a libtool module */
1689 if (handle
->loader
->sym_prefix
) {
1690 strcpy(sym
, handle
->loader
->sym_prefix
);
1691 strcat(sym
, handle
->info
.name
);
1693 strcpy(sym
, handle
->info
.name
);
1694 strcat(sym
, "_LTX_");
1695 strcat(sym
, symbol
);
1696 /* try "modulename_LTX_symbol" */
1697 address
= handle
->loader
->find_sym(data
, handle
->module
, sym
);
1703 last_error
= saved_error
;
1705 /* otherwise try "symbol" */
1706 if (handle
->loader
->sym_prefix
) {
1707 strcpy(sym
, handle
->loader
->sym_prefix
);
1708 strcat(sym
, symbol
);
1710 strcpy(sym
, symbol
);
1711 address
= handle
->loader
->find_sym(data
, handle
->module
, sym
);
1718 lt_dlerror
LTDL_PARAMS((void))
1720 const char *error
= last_error
;
1727 lt_dladdsearchdir (search_dir
)
1728 const char *search_dir
;
1730 if (!search_dir
|| !strlen(search_dir
))
1732 if (!user_search_path
) {
1733 user_search_path
= strdup(search_dir
);
1734 if (!user_search_path
) {
1735 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1739 char *new_search_path
= (char*)
1740 lt_dlmalloc(strlen(user_search_path
) +
1741 strlen(search_dir
) + 2); /* ':' + '\0' == 2 */
1742 if (!new_search_path
) {
1743 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1746 sprintf (new_search_path
, "%s%c%s", user_search_path
,
1747 LTDL_PATHSEP_CHAR
, search_dir
);
1748 lt_dlfree(user_search_path
);
1749 user_search_path
= new_search_path
;
1755 lt_dlsetsearchpath (search_path
)
1756 const char *search_path
;
1758 if (user_search_path
)
1759 lt_dlfree(user_search_path
);
1760 user_search_path
= 0; /* reset the search path */
1761 if (!search_path
|| !strlen(search_path
))
1763 user_search_path
= strdup(search_path
);
1764 if (!user_search_path
)
1770 lt_dlgetsearchpath
LTDL_PARAMS((void))
1772 return user_search_path
;
1776 lt_dlgetinfo (handle
)
1780 last_error
= LT_DLSTRERROR(INVALID_HANDLE
);
1783 return &(handle
->info
);
1787 lt_dlforeach (func
, data
)
1788 int (*func
) LTDL_PARAMS((lt_dlhandle handle
, lt_ptr_t data
));
1791 lt_dlhandle cur
= handles
;
1793 lt_dlhandle tmp
= cur
;
1795 if (func(tmp
, data
))
1802 lt_dlloader_add (place
, dlloader
, loader_name
)
1803 lt_dlloader_t
*place
;
1804 const struct lt_user_dlloader
*dlloader
;
1805 const char *loader_name
;
1807 lt_dlloader_t
*node
= 0, *ptr
= 0;
1809 if ((dlloader
== 0) /* diagnose null parameters */
1810 || (dlloader
->module_open
== 0)
1811 || (dlloader
->module_close
== 0)
1812 || (dlloader
->find_sym
== 0)) {
1813 last_error
= LT_DLSTRERROR(INVALID_LOADER
);
1817 /* Create a new dlloader node with copies of the user callbacks. */
1818 node
= (lt_dlloader_t
*) lt_dlmalloc (sizeof (lt_dlloader_t
));
1820 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1824 node
->loader_name
= loader_name
;
1825 node
->sym_prefix
= dlloader
->sym_prefix
;
1826 node
->dlloader_exit
= dlloader
->dlloader_exit
;
1827 node
->module_open
= dlloader
->module_open
;
1828 node
->module_close
= dlloader
->module_close
;
1829 node
->find_sym
= dlloader
->find_sym
;
1830 node
->dlloader_data
= dlloader
->dlloader_data
;
1833 /* If there are no loaders, NODE becomes the list! */
1836 /* If PLACE is not set, add NODE to the end of the
1838 for (ptr
= loaders
; ptr
->next
; ptr
= ptr
->next
)
1841 } else if (loaders
== place
) {
1842 /* If PLACE is the first loader, NODE goes first. */
1846 /* Find the node immediately preceding PLACE. */
1847 for (ptr
= loaders
; ptr
->next
!= place
; ptr
= ptr
->next
)
1850 if (ptr
->next
!= place
) {
1851 last_error
= LT_DLSTRERROR(INVALID_LOADER
);
1855 /* Insert NODE between PTR and PLACE. */
1864 lt_dlloader_remove (loader_name
)
1865 const char *loader_name
;
1867 lt_dlloader_t
*place
= lt_dlloader_find (loader_name
);
1872 last_error
= LT_DLSTRERROR(INVALID_LOADER
);
1876 /* Fail if there are any open modules which use this loader. */
1877 for (handle
= handles
; handle
; handle
= handle
->next
)
1878 if (handle
->loader
== place
) {
1879 last_error
= LT_DLSTRERROR(REMOVE_LOADER
);
1883 if (place
== loaders
)
1884 /* PLACE is the first loader in the list. */
1885 loaders
= loaders
->next
;
1887 /* Find the loader before the one being removed. */
1888 lt_dlloader_t
*prev
;
1889 for (prev
= loaders
; prev
->next
; prev
= prev
->next
)
1890 if (!strcmp (prev
->next
->loader_name
, loader_name
))
1894 prev
->next
= prev
->next
->next
;
1896 if (place
->dlloader_exit
)
1897 result
= place
->dlloader_exit (place
->dlloader_data
);
1904 lt_dlloader_next (place
)
1905 lt_dlloader_t
*place
;
1907 return place
? place
->next
: loaders
;
1911 lt_dlloader_name (place
)
1912 lt_dlloader_t
*place
;
1915 last_error
= LT_DLSTRERROR(INVALID_LOADER
);
1916 return place
? place
->loader_name
: 0;
1919 lt_dlloader_data_t
*
1920 lt_dlloader_data (place
)
1921 lt_dlloader_t
*place
;
1924 last_error
= LT_DLSTRERROR(INVALID_LOADER
);
1925 return place
? &(place
->dlloader_data
) : 0;
1929 lt_dlloader_find (loader_name
)
1930 const char *loader_name
;
1932 lt_dlloader_t
*place
= 0;
1934 for (place
= loaders
; place
; place
= place
->next
)
1935 if (strcmp (place
->loader_name
, loader_name
) == 0)
1941 static const char **user_error_strings
= 0;
1942 static int errorcode
= LTDL_ERROR_MAX
;
1945 lt_dladderror (diagnostic
)
1946 const char *diagnostic
;
1948 int index
= errorcode
- LTDL_ERROR_MAX
;
1949 const char **temp
= 0;
1951 /* realloc is not entirely portable, so simulate it using
1952 lt_dlmalloc and lt_dlfree. */
1953 temp
= (const char **) lt_dlmalloc ((1+index
) * sizeof(const char*));
1955 last_error
= LT_DLSTRERROR(NO_MEMORY
);
1959 /* Build the new vector in the memory addressed by temp. */
1960 temp
[index
] = diagnostic
;
1961 while (--index
>= 0)
1962 temp
[index
] = user_error_strings
[index
];
1964 lt_dlfree (user_error_strings
);
1965 user_error_strings
= temp
;
1970 lt_dlseterror (index
)
1973 if (index
>= errorcode
|| index
< 0) {
1974 last_error
= LT_DLSTRERROR(INVALID_ERRORCODE
);
1978 if (index
< LTDL_ERROR_MAX
)
1979 last_error
= ltdl_error_strings
[errorcode
];
1981 last_error
= user_error_strings
[errorcode
- LTDL_ERROR_MAX
];