1 /* ltdl.c -- system independent dlopen wrapper
3 Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006,
4 2007, 2008, 2011 Free Software Foundation, Inc.
5 Written by Thomas Tanner, 1998
7 NOTE: The canonical source of this file is maintained with the
8 GNU Libtool package. Report bugs to bug-libtool@gnu.org.
10 GNU Libltdl is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
15 As a special exception to the GNU Lesser General Public License,
16 if you distribute this file as part of a program or library that
17 is built using GNU Libtool, you may include this file under the
18 same distribution terms that you use for the rest of that program.
20 GNU Libltdl is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU Lesser General Public License for more details.
25 You should have received a copy of the GNU Lesser General Public
26 License along with GNU Libltdl; see the file COPYING.LIB. If not, a
27 copy can be downloaded from http://www.gnu.org/licenses/lgpl.html,
28 or obtained by writing to the Free Software Foundation, Inc.,
29 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
32 #include "lt__private.h"
33 #include "lt_system.h"
34 #include "lt_dlloader.h"
37 /* --- MANIFEST CONSTANTS --- */
40 /* Standard libltdl search path environment variable name */
41 #undef LTDL_SEARCHPATH_VAR
42 #define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
44 /* Standard libtool archive file extension. */
46 #define LT_ARCHIVE_EXT ".la"
48 /* max. filename length */
49 #if !defined(LT_FILENAME_MAX)
50 # define LT_FILENAME_MAX 1024
53 #if !defined(LT_LIBEXT)
54 # define LT_LIBEXT "a"
57 #if !defined(LT_LIBPREFIX)
58 # define LT_LIBPREFIX "lib"
61 /* This is the maximum symbol size that won't require malloc/free */
62 #undef LT_SYMBOL_LENGTH
63 #define LT_SYMBOL_LENGTH 128
65 /* This accounts for the _LTX_ separator */
66 #undef LT_SYMBOL_OVERHEAD
67 #define LT_SYMBOL_OVERHEAD 5
69 /* Various boolean flags can be stored in the flags field of an
71 #define LT_DLIS_RESIDENT(handle) ((handle)->info.is_resident)
72 #define LT_DLIS_SYMGLOBAL(handle) ((handle)->info.is_symglobal)
73 #define LT_DLIS_SYMLOCAL(handle) ((handle)->info.is_symlocal)
76 static const char objdir
[] = LT_OBJDIR
;
77 static const char archive_ext
[] = LT_ARCHIVE_EXT
;
78 static const char libext
[] = LT_LIBEXT
;
79 static const char libprefix
[] = LT_LIBPREFIX
;
80 #if defined(LT_MODULE_EXT)
81 static const char shlib_ext
[] = LT_MODULE_EXT
;
83 /* If the loadable module suffix is not the same as the linkable
84 * shared library suffix, this will be defined. */
85 #if defined(LT_SHARED_EXT)
86 static const char shared_ext
[] = LT_SHARED_EXT
;
88 #if defined(LT_DLSEARCH_PATH)
89 static const char sys_dlsearch_path
[] = LT_DLSEARCH_PATH
;
95 /* --- DYNAMIC MODULE LOADING --- */
98 /* The type of a function used at each iteration of foreach_dirinpath(). */
99 typedef int foreach_callback_func (char *filename
, void *data1
,
101 /* foreachfile_callback itself calls a function of this type: */
102 typedef int file_worker_func (const char *filename
, void *data
);
105 static int foreach_dirinpath (const char *search_path
,
106 const char *base_name
,
107 foreach_callback_func
*func
,
108 void *data1
, void *data2
);
109 static int find_file_callback (char *filename
, void *data1
,
111 static int find_handle_callback (char *filename
, void *data
,
113 static int foreachfile_callback (char *filename
, void *data1
,
117 static int canonicalize_path (const char *path
, char **pcanonical
);
118 static int argzize_path (const char *path
,
119 char **pargz
, size_t *pargz_len
);
120 static FILE *find_file (const char *search_path
,
121 const char *base_name
, char **pdir
);
122 static lt_dlhandle
*find_handle (const char *search_path
,
123 const char *base_name
,
126 static int find_module (lt_dlhandle
*handle
, const char *dir
,
127 const char *libdir
, const char *dlname
,
128 const char *old_name
, int installed
,
130 static int has_library_ext (const char *filename
);
131 static int load_deplibs (lt_dlhandle handle
, char *deplibs
);
132 static int trim (char **dest
, const char *str
);
133 static int try_dlopen (lt_dlhandle
*handle
,
134 const char *filename
, const char *ext
,
136 static int tryall_dlopen (lt_dlhandle
*handle
,
137 const char *filename
,
139 const lt_dlvtable
*vtable
);
140 static int unload_deplibs (lt_dlhandle handle
);
141 static int lt_argz_insert (char **pargz
, size_t *pargz_len
,
142 char *before
, const char *entry
);
143 static int lt_argz_insertinorder (char **pargz
, size_t *pargz_len
,
145 static int lt_argz_insertdir (char **pargz
, size_t *pargz_len
,
146 const char *dirnam
, struct dirent
*dp
);
147 static int lt_dlpath_insertdir (char **ppath
, char *before
,
149 static int list_files_by_dir (const char *dirnam
,
150 char **pargz
, size_t *pargz_len
);
151 static int file_not_found (void);
153 #ifdef HAVE_LIBDLLOADER
154 static int loader_init_callback (lt_dlhandle handle
);
155 #endif /* HAVE_LIBDLLOADER */
157 static int loader_init (lt_get_vtable
*vtable_func
,
160 static char *user_search_path
= 0;
161 static lt_dlhandle handles
= 0;
162 static int initialized
= 0;
164 /* Our memory failure callback sets the error message to be passed back
165 up to the client, so we must be careful to return from mallocation
166 callers if allocation fails (as this callback returns!!). */
168 lt__alloc_die_callback (void)
170 LT__SETERROR (NO_MEMORY
);
173 #ifdef HAVE_LIBDLLOADER
174 /* This function is called to initialise each preloaded module loader,
175 and hook it into the list of loaders to be used when attempting to
176 dlopen an application module. */
178 loader_init_callback (lt_dlhandle handle
)
180 lt_get_vtable
*vtable_func
= (lt_get_vtable
*) lt_dlsym (handle
, "get_vtable");
181 return loader_init (vtable_func
, 0);
183 #endif /* HAVE_LIBDLLOADER */
186 loader_init (lt_get_vtable
*vtable_func
, lt_user_data data
)
188 const lt_dlvtable
*vtable
= 0;
193 vtable
= (*vtable_func
) (data
);
196 /* lt_dlloader_add will LT__SETERROR if it fails. */
197 errors
+= lt_dlloader_add (vtable
);
199 assert (errors
|| vtable
);
201 if ((!errors
) && vtable
->dlloader_init
)
203 if ((*vtable
->dlloader_init
) (vtable
->dlloader_data
))
205 LT__SETERROR (INIT_LOADER
);
213 /* Bootstrap the loader loading with the preopening loader. */
214 #define get_vtable preopen_LTX_get_vtable
215 #define preloaded_symbols LT_CONC3(lt_, LTDLOPEN, _LTX_preloaded_symbols)
218 LT_SCOPE
const lt_dlvtable
* get_vtable (lt_user_data data
);
220 #ifdef HAVE_LIBDLLOADER
221 extern LT_DLSYM_CONST lt_dlsymlist preloaded_symbols
[];
224 /* Initialize libltdl. */
230 /* Initialize only at first call. */
231 if (++initialized
== 1)
233 lt__alloc_die
= lt__alloc_die_callback
;
235 user_search_path
= 0; /* empty search path */
237 /* First set up the statically loaded preload module loader, so
238 we can use it to preopen the other loaders we linked in at
240 errors
+= loader_init (get_vtable
, 0);
242 /* Now open all the preloaded module loaders, so the application
243 can use _them_ to lt_dlopen its own modules. */
244 #ifdef HAVE_LIBDLLOADER
247 errors
+= lt_dlpreload (preloaded_symbols
);
252 errors
+= lt_dlpreload_open (LT_STR(LTDLOPEN
), loader_init_callback
);
254 #endif /* HAVE_LIBDLLOADER */
257 #ifdef LT_DEBUG_LOADERS
267 /* shut down libltdl */
268 lt_dlloader
*loader
= 0;
269 lt_dlhandle handle
= handles
;
274 LT__SETERROR (SHUTDOWN
);
279 /* shut down only at last call. */
280 if (--initialized
== 0)
284 while (handles
&& LT_DLIS_RESIDENT (handles
))
286 handles
= handles
->next
;
289 /* close all modules */
290 for (level
= 1; handle
; ++level
)
292 lt_dlhandle cur
= handles
;
293 int saw_nonresident
= 0;
297 lt_dlhandle tmp
= cur
;
299 if (!LT_DLIS_RESIDENT (tmp
))
302 if (tmp
->info
.ref_count
<= level
)
304 if (lt_dlclose (tmp
))
308 /* Make sure that the handle pointed to by 'cur' still exists.
309 lt_dlclose recursively closes dependent libraries which removes
310 them from the linked list. One of these might be the one
311 pointed to by 'cur'. */
314 for (tmp
= handles
; tmp
; tmp
= tmp
->next
)
323 /* done if only resident modules are left */
324 if (!saw_nonresident
)
328 /* When removing loaders, we can only find out failure by testing
329 the error string, so avoid a spurious one from an earlier
334 /* close all loaders */
335 for (loader
= (lt_dlloader
*) lt_dlloader_next (NULL
); loader
;)
337 lt_dlloader
*next
= (lt_dlloader
*) lt_dlloader_next (loader
);
338 lt_dlvtable
*vtable
= (lt_dlvtable
*) lt_dlloader_get (loader
);
340 if ((vtable
= lt_dlloader_remove ((char *) vtable
->name
)))
346 /* ignore errors due to resident modules */
356 FREE(user_search_path
);
364 /* Try VTABLE or, if VTABLE is NULL, all available loaders for FILENAME.
365 If the library is not successfully loaded, return non-zero. Otherwise,
366 the dlhandle is stored at the address given in PHANDLE. */
368 tryall_dlopen (lt_dlhandle
*phandle
, const char *filename
,
369 lt_dladvise advise
, const lt_dlvtable
*vtable
)
371 lt_dlhandle handle
= handles
;
372 const char * saved_error
= 0;
375 #ifdef LT_DEBUG_LOADERS
376 fprintf (stderr
, "tryall_dlopen (%s, %s)\n",
377 filename
? filename
: "(null)",
378 vtable
? vtable
->name
: "(ALL)");
381 LT__GETERROR (saved_error
);
383 /* check whether the module was already opened */
384 for (;handle
; handle
= handle
->next
)
386 if ((handle
->info
.filename
== filename
) /* dlopen self: 0 == 0 */
387 || (handle
->info
.filename
&& filename
388 && streq (handle
->info
.filename
, filename
)))
396 ++handle
->info
.ref_count
;
404 /* Comment out the check of file permissions using access.
405 This call seems to always return -1 with error EACCES.
407 /* We need to catch missing file errors early so that
408 file_not_found() can detect what happened.
409 if (access (filename, R_OK) != 0)
411 LT__SETERROR (FILE_NOT_FOUND);
416 handle
->info
.filename
= lt__strdup (filename
);
417 if (!handle
->info
.filename
)
425 handle
->info
.filename
= 0;
429 lt_dlloader loader
= lt_dlloader_next (0);
430 const lt_dlvtable
*loader_vtable
;
435 loader_vtable
= vtable
;
437 loader_vtable
= lt_dlloader_get (loader
);
439 #ifdef LT_DEBUG_LOADERS
440 fprintf (stderr
, "Calling %s->module_open (%s)\n",
441 (loader_vtable
&& loader_vtable
->name
) ? loader_vtable
->name
: "(null)",
442 filename
? filename
: "(null)");
444 handle
->module
= (*loader_vtable
->module_open
) (loader_vtable
->dlloader_data
,
446 #ifdef LT_DEBUG_LOADERS
447 fprintf (stderr
, " Result: %s\n",
448 handle
->module
? "Success" : "Failed");
451 if (handle
->module
!= 0)
455 handle
->info
.is_resident
= advise
->is_resident
;
456 handle
->info
.is_symglobal
= advise
->is_symglobal
;
457 handle
->info
.is_symlocal
= advise
->is_symlocal
;
462 while (!vtable
&& (loader
= lt_dlloader_next (loader
)));
464 /* If VTABLE was given but couldn't open the module, or VTABLE wasn't
465 given but we exhausted all loaders without opening the module, bail
467 if ((vtable
&& !handle
->module
)
468 || (!vtable
&& !loader
))
470 FREE (handle
->info
.filename
);
475 handle
->vtable
= loader_vtable
;
478 LT__SETERRORSTR (saved_error
);
486 tryall_dlopen_module (lt_dlhandle
*handle
, const char *prefix
,
487 const char *dirname
, const char *dlname
,
492 size_t filename_len
= 0;
493 size_t dirname_len
= LT_STRLEN (dirname
);
498 #if defined(LT_DIRSEP_CHAR)
499 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
500 should make it into this function: */
501 assert (strchr (dirname
, LT_DIRSEP_CHAR
) == 0);
505 if (dirname
[dirname_len
-1] == '/')
507 filename_len
= dirname_len
+ 1 + LT_STRLEN (dlname
);
509 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
510 The PREFIX (if any) is handled below. */
511 filename
= MALLOC (char, filename_len
+ 1);
515 sprintf (filename
, "%.*s/%s", (int) dirname_len
, dirname
, dlname
);
517 /* Now that we have combined DIRNAME and MODULENAME, if there is
518 also a PREFIX to contend with, simply recurse with the arguments
519 shuffled. Otherwise, attempt to open FILENAME as a module. */
522 error
+= tryall_dlopen_module (handle
, (const char *) 0,
523 prefix
, filename
, advise
);
525 else if (tryall_dlopen (handle
, filename
, advise
, 0) != 0)
535 find_module (lt_dlhandle
*handle
, const char *dir
, const char *libdir
,
536 const char *dlname
, const char *old_name
, int installed
,
539 /* Try to open the old library first; if it was dlpreopened,
540 we want the preopened version of it, even if a dlopenable
541 module is available. */
542 if (old_name
&& tryall_dlopen (handle
, old_name
,
543 advise
, lt_dlloader_find ("lt_preopen") ) == 0)
548 /* Try to open the dynamic library. */
551 /* try to open the installed module */
552 if (installed
&& libdir
)
554 if (tryall_dlopen_module (handle
, (const char *) 0,
555 libdir
, dlname
, advise
) == 0)
559 /* try to open the not-installed module */
562 if (tryall_dlopen_module (handle
, dir
, objdir
,
563 dlname
, advise
) == 0)
567 /* maybe it was moved to another directory */
569 if (dir
&& (tryall_dlopen_module (handle
, (const char *) 0,
570 dir
, dlname
, advise
) == 0))
580 canonicalize_path (const char *path
, char **pcanonical
)
584 assert (path
&& *path
);
587 canonical
= MALLOC (char, 1+ LT_STRLEN (path
));
594 for (src
= 0; path
[src
] != LT_EOS_CHAR
; ++src
)
596 /* Path separators are not copied to the beginning or end of
597 the destination, or if another separator would follow
599 if (path
[src
] == LT_PATHSEP_CHAR
)
602 || (path
[1+ src
] == LT_PATHSEP_CHAR
)
603 || (path
[1+ src
] == LT_EOS_CHAR
))
607 /* Anything other than a directory separator is copied verbatim. */
608 if ((path
[src
] != '/')
609 #if defined(LT_DIRSEP_CHAR)
610 && (path
[src
] != LT_DIRSEP_CHAR
)
614 canonical
[dest
++] = path
[src
];
616 /* Directory separators are converted and copied only if they are
617 not at the end of a path -- i.e. before a path separator or
619 else if ((path
[1+ src
] != LT_PATHSEP_CHAR
)
620 && (path
[1+ src
] != LT_EOS_CHAR
)
621 #if defined(LT_DIRSEP_CHAR)
622 && (path
[1+ src
] != LT_DIRSEP_CHAR
)
624 && (path
[1+ src
] != '/'))
626 canonical
[dest
++] = '/';
630 /* Add an end-of-string marker at the end. */
631 canonical
[dest
] = LT_EOS_CHAR
;
634 /* Assign new value. */
635 *pcanonical
= canonical
;
641 argzize_path (const char *path
, char **pargz
, size_t *pargz_len
)
649 if ((error
= argz_create_sep (path
, LT_PATHSEP_CHAR
, pargz
, pargz_len
)))
654 LT__SETERROR (NO_MEMORY
);
657 LT__SETERROR (UNKNOWN
);
667 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
668 of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
669 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
670 it is appended to each SEARCH_PATH element before FUNC is called. */
672 foreach_dirinpath (const char *search_path
, const char *base_name
,
673 foreach_callback_func
*func
, void *data1
, void *data2
)
676 size_t filenamesize
= 0;
677 size_t lenbase
= LT_STRLEN (base_name
);
683 if (!search_path
|| !*search_path
)
685 LT__SETERROR (FILE_NOT_FOUND
);
689 if (canonicalize_path (search_path
, &canonical
) != 0)
692 if (argzize_path (canonical
, &argz
, &argz_len
) != 0)
697 while ((dir_name
= argz_next (argz
, argz_len
, dir_name
)))
699 size_t lendir
= LT_STRLEN (dir_name
);
701 if (1+ lendir
+ lenbase
>= filenamesize
)
704 filenamesize
= 1+ lendir
+ 1+ lenbase
; /* "/d" + '/' + "f" + '\0' */
705 filename
= MALLOC (char, filenamesize
);
710 assert (filenamesize
> lendir
);
711 strcpy (filename
, dir_name
);
713 if (base_name
&& *base_name
)
715 if (filename
[lendir
-1] != '/')
716 filename
[lendir
++] = '/';
717 strcpy (filename
+lendir
, base_name
);
720 if ((result
= (*func
) (filename
, data1
, data2
)))
735 /* If FILEPATH can be opened, store the name of the directory component
736 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
737 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
739 find_file_callback (char *filename
, void *data1
, void *data2
)
741 char **pdir
= (char **) data1
;
742 FILE **pfile
= (FILE **) data2
;
745 assert (filename
&& *filename
);
749 if ((*pfile
= fopen (filename
, LT_READTEXT_MODE
)))
751 char *dirend
= strrchr (filename
, '/');
753 if (dirend
> filename
)
754 *dirend
= LT_EOS_CHAR
;
757 *pdir
= lt__strdup (filename
);
758 is_done
= (*pdir
== 0) ? -1 : 1;
765 find_file (const char *search_path
, const char *base_name
, char **pdir
)
769 foreach_dirinpath (search_path
, base_name
, find_file_callback
, pdir
, &file
);
775 find_handle_callback (char *filename
, void *data
, void *data2
)
777 lt_dlhandle
*phandle
= (lt_dlhandle
*) data
;
778 int notfound
= access (filename
, R_OK
);
779 lt_dladvise advise
= (lt_dladvise
) data2
;
781 /* Bail out if file cannot be read... */
785 /* Try to dlopen the file, but do not continue searching in any
787 if (tryall_dlopen (phandle
, filename
, advise
, 0) != 0)
793 /* If HANDLE was found return it, otherwise return 0. If HANDLE was
794 found but could not be opened, *HANDLE will be set to 0. */
796 find_handle (const char *search_path
, const char *base_name
,
797 lt_dlhandle
*phandle
, lt_dladvise advise
)
802 if (!foreach_dirinpath (search_path
, base_name
, find_handle_callback
,
809 #if !defined(LTDL_DLOPEN_DEPLIBS)
811 load_deplibs (lt_dlhandle handle
, char * LT__UNUSED deplibs
)
813 handle
->depcount
= 0;
817 #else /* defined(LTDL_DLOPEN_DEPLIBS) */
819 load_deplibs (lt_dlhandle handle
, char *deplibs
)
821 char *p
, *save_search_path
= 0;
827 handle
->depcount
= 0;
835 if (user_search_path
)
837 save_search_path
= lt__strdup (user_search_path
);
838 if (!save_search_path
)
842 /* extract search paths and count deplibs */
846 if (!isspace ((unsigned char) *p
))
849 while (*end
&& !isspace((unsigned char) *end
))
854 if (strncmp(p
, "-L", 2) == 0 || strncmp(p
, "-R", 2) == 0)
857 *end
= 0; /* set a temporary string terminator */
858 if (lt_dladdsearchdir(p
+2))
884 names
= MALLOC (char *, depcount
);
888 /* now only extract the actual deplibs */
893 if (isspace ((unsigned char) *p
))
900 while (*end
&& !isspace ((unsigned char) *end
))
905 if (strncmp(p
, "-L", 2) != 0 && strncmp(p
, "-R", 2) != 0)
909 *end
= 0; /* set a temporary string terminator */
910 if (strncmp(p
, "-l", 2) == 0)
912 size_t name_len
= 3+ /* "lib" */ LT_STRLEN (p
+ 2);
913 name
= MALLOC (char, 1+ name_len
);
915 sprintf (name
, "lib%s", p
+2);
918 name
= lt__strdup(p
);
923 names
[depcount
++] = name
;
930 /* load the deplibs (in reverse order)
931 At this stage, don't worry if the deplibs do not load correctly,
932 they may already be statically linked into the loading application
933 for instance. There will be a more enlightening error message
934 later on if the loaded module cannot resolve all of its symbols. */
937 lt_dlhandle cur
= handle
;
940 cur
->deplibs
= MALLOC (lt_dlhandle
, depcount
);
944 for (i
= 0; i
< depcount
; ++i
)
946 cur
->deplibs
[j
] = lt_dlopenext(names
[depcount
-1-i
]);
953 cur
->depcount
= j
; /* Number of successfully loaded deplibs */
958 for (i
= 0; i
< depcount
; ++i
)
965 /* restore the old search path */
966 if (save_search_path
) {
967 MEMREASSIGN (user_search_path
, save_search_path
);
972 #endif /* defined(LTDL_DLOPEN_DEPLIBS) */
975 unload_deplibs (lt_dlhandle handle
)
979 lt_dlhandle cur
= handle
;
983 for (i
= 0; i
< cur
->depcount
; ++i
)
985 if (!LT_DLIS_RESIDENT (cur
->deplibs
[i
]))
987 errors
+= lt_dlclose (cur
->deplibs
[i
]);
997 trim (char **dest
, const char *str
)
999 /* remove the leading and trailing "'" from str
1000 and store the result in dest */
1001 const char *end
= strrchr (str
, '\'');
1002 size_t len
= LT_STRLEN (str
);
1007 if (!end
|| end
== str
)
1010 if (len
> 3 && str
[0] == '\'')
1012 tmp
= MALLOC (char, end
- str
);
1016 memcpy(tmp
, &str
[1], (end
- str
) - 1);
1017 tmp
[(end
- str
) - 1] = LT_EOS_CHAR
;
1028 /* Read the .la file FILE. */
1030 parse_dotla_file(FILE *file
, char **dlname
, char **libdir
, char **deplibs
,
1031 char **old_name
, int *installed
)
1034 size_t line_len
= LT_FILENAME_MAX
;
1035 char * line
= MALLOC (char, line_len
);
1039 LT__SETERROR (FILE_NOT_FOUND
);
1043 while (!feof (file
))
1045 line
[line_len
-2] = '\0';
1046 if (!fgets (line
, (int) line_len
, file
))
1051 /* Handle the case where we occasionally need to read a line
1052 that is longer than the initial buffer size.
1053 Behave even if the file contains NUL bytes due to corruption. */
1054 while (line
[line_len
-2] != '\0' && line
[line_len
-2] != '\n' && !feof (file
))
1056 line
= REALLOC (char, line
, line_len
*2);
1062 line
[line_len
* 2 - 2] = '\0';
1063 if (!fgets (&line
[line_len
-1], (int) line_len
+1, file
))
1070 if (line
[0] == '\n' || line
[0] == '#')
1076 #define STR_DLNAME "dlname="
1077 if (strncmp (line
, STR_DLNAME
, sizeof (STR_DLNAME
) - 1) == 0)
1079 errors
+= trim (dlname
, &line
[sizeof (STR_DLNAME
) - 1]);
1082 #undef STR_OLD_LIBRARY
1083 #define STR_OLD_LIBRARY "old_library="
1084 else if (strncmp (line
, STR_OLD_LIBRARY
,
1085 sizeof (STR_OLD_LIBRARY
) - 1) == 0)
1087 errors
+= trim (old_name
, &line
[sizeof (STR_OLD_LIBRARY
) - 1]);
1090 /* Windows native tools do not understand the POSIX paths we store
1093 #define STR_LIBDIR "libdir="
1094 else if (strncmp (line
, STR_LIBDIR
, sizeof (STR_LIBDIR
) - 1) == 0)
1096 errors
+= trim (libdir
, &line
[sizeof(STR_LIBDIR
) - 1]);
1098 /* Disallow following unix-style paths on MinGW. */
1099 if (*libdir
&& (**libdir
== '/' || **libdir
== '\\'))
1104 #undef STR_DL_DEPLIBS
1105 #define STR_DL_DEPLIBS "dependency_libs="
1106 else if (strncmp (line
, STR_DL_DEPLIBS
,
1107 sizeof (STR_DL_DEPLIBS
) - 1) == 0)
1109 errors
+= trim (deplibs
, &line
[sizeof (STR_DL_DEPLIBS
) - 1]);
1111 else if (streq (line
, "installed=yes\n"))
1115 else if (streq (line
, "installed=no\n"))
1120 #undef STR_LIBRARY_NAMES
1121 #define STR_LIBRARY_NAMES "library_names="
1122 else if (!*dlname
&& strncmp (line
, STR_LIBRARY_NAMES
,
1123 sizeof (STR_LIBRARY_NAMES
) - 1) == 0)
1126 errors
+= trim (dlname
, &line
[sizeof (STR_LIBRARY_NAMES
) - 1]);
1129 && (last_libname
= strrchr (*dlname
, ' ')) != 0)
1131 last_libname
= lt__strdup (last_libname
+ 1);
1137 MEMREASSIGN (*dlname
, last_libname
);
1150 /* Try to open FILENAME as a module. */
1152 try_dlopen (lt_dlhandle
*phandle
, const char *filename
, const char *ext
,
1155 const char * saved_error
= 0;
1156 char * archive_name
= 0;
1157 char * canonical
= 0;
1158 char * base_name
= 0;
1163 lt_dlhandle newhandle
;
1166 assert (*phandle
== 0);
1168 #ifdef LT_DEBUG_LOADERS
1169 fprintf (stderr
, "try_dlopen (%s, %s)\n",
1170 filename
? filename
: "(null)",
1171 ext
? ext
: "(null)");
1174 LT__GETERROR (saved_error
);
1179 *phandle
= (lt_dlhandle
) lt__zalloc (sizeof (struct lt__handle
));
1183 newhandle
= *phandle
;
1185 /* lt_dlclose()ing yourself is very bad! Disallow it. */
1186 newhandle
->info
.is_resident
= 1;
1188 if (tryall_dlopen (&newhandle
, 0, advise
, 0) != 0)
1194 goto register_handle
;
1197 assert (filename
&& *filename
);
1201 attempt
= MALLOC (char, LT_STRLEN (filename
) + LT_STRLEN (ext
) + 1);
1205 sprintf(attempt
, "%s%s", filename
, ext
);
1209 attempt
= lt__strdup (filename
);
1214 /* Doing this immediately allows internal functions to safely
1215 assume only canonicalized paths are passed. */
1216 if (canonicalize_path (attempt
, &canonical
) != 0)
1222 /* If the canonical module name is a path (relative or absolute)
1223 then split it into a directory part and a name part. */
1224 base_name
= strrchr (canonical
, '/');
1227 size_t dirlen
= (1+ base_name
) - canonical
;
1229 dir
= MALLOC (char, 1+ dirlen
);
1236 strncpy (dir
, canonical
, dirlen
);
1237 dir
[dirlen
] = LT_EOS_CHAR
;
1242 MEMREASSIGN (base_name
, canonical
);
1244 assert (base_name
&& *base_name
);
1246 ext
= strrchr (base_name
, '.');
1249 ext
= base_name
+ LT_STRLEN (base_name
);
1252 /* extract the module name from the file name */
1253 name
= MALLOC (char, ext
- base_name
+ 1);
1260 /* canonicalize the module name */
1263 for (i
= 0; i
< ext
- base_name
; ++i
)
1265 if (isalnum ((unsigned char)(base_name
[i
])))
1267 name
[i
] = base_name
[i
];
1274 name
[ext
- base_name
] = LT_EOS_CHAR
;
1277 /* Before trawling through the filesystem in search of a module,
1278 check whether we are opening a preloaded module. */
1281 const lt_dlvtable
*vtable
= lt_dlloader_find ("lt_preopen");
1285 /* libprefix + name + "." + libext + NULL */
1286 archive_name
= MALLOC (char, strlen (libprefix
) + LT_STRLEN (name
) + strlen (libext
) + 2);
1287 *phandle
= (lt_dlhandle
) lt__zalloc (sizeof (struct lt__handle
));
1289 if ((*phandle
== NULL
) || (archive_name
== NULL
))
1294 newhandle
= *phandle
;
1296 /* Preloaded modules are always named according to their old
1298 if (strncmp(name
, "lib", 3) == 0)
1300 sprintf (archive_name
, "%s%s.%s", libprefix
, name
+ 3, libext
);
1304 sprintf (archive_name
, "%s.%s", name
, libext
);
1307 if (tryall_dlopen (&newhandle
, archive_name
, advise
, vtable
) == 0)
1309 goto register_handle
;
1312 /* If we're still here, there was no matching preloaded module,
1313 so put things back as we found them, and continue searching. */
1319 /* If we are allowing only preloaded modules, and we didn't find
1320 anything yet, give up on the search here. */
1321 if (advise
&& advise
->try_preload_only
)
1326 /* Check whether we are opening a libtool module (.la extension). */
1327 if (ext
&& streq (ext
, archive_ext
))
1329 /* this seems to be a libtool module */
1332 char * old_name
= 0;
1336 /* if we can't find the installed flag, it is probably an
1337 installed libtool archive, produced with an old version
1341 /* Now try to open the .la file. If there is no directory name
1342 component, try to find it first in user_search_path and then other
1343 prescribed paths. Otherwise (or in any case if the module was not
1344 yet found) try opening just the module name as passed. */
1347 const char *search_path
= user_search_path
;
1350 file
= find_file (user_search_path
, base_name
, &dir
);
1354 search_path
= getenv (LTDL_SEARCHPATH_VAR
);
1356 file
= find_file (search_path
, base_name
, &dir
);
1359 #if defined(LT_MODULE_PATH_VAR)
1362 search_path
= getenv (LT_MODULE_PATH_VAR
);
1364 file
= find_file (search_path
, base_name
, &dir
);
1367 #if defined(LT_DLSEARCH_PATH)
1368 if (!file
&& *sys_dlsearch_path
)
1370 file
= find_file (sys_dlsearch_path
, base_name
, &dir
);
1376 file
= fopen (attempt
, LT_READTEXT_MODE
);
1379 /* If we didn't find the file by now, it really isn't there. Set
1380 the status flag, and bail out. */
1383 LT__SETERROR (FILE_NOT_FOUND
);
1388 /* read the .la file */
1389 if (parse_dotla_file(file
, &dlname
, &libdir
, &deplibs
,
1390 &old_name
, &installed
) != 0)
1395 /* allocate the handle */
1396 *phandle
= (lt_dlhandle
) lt__zalloc (sizeof (struct lt__handle
));
1412 if (load_deplibs (*phandle
, deplibs
) == 0)
1414 newhandle
= *phandle
;
1415 /* find_module may replace newhandle */
1416 if (find_module (&newhandle
, dir
, libdir
, dlname
, old_name
,
1419 unload_deplibs (*phandle
);
1439 if (*phandle
!= newhandle
)
1441 unload_deplibs (*phandle
);
1446 /* not a libtool module */
1447 *phandle
= (lt_dlhandle
) lt__zalloc (sizeof (struct lt__handle
));
1454 newhandle
= *phandle
;
1456 /* If the module has no directory name component, try to find it
1457 first in user_search_path and then other prescribed paths.
1458 Otherwise (or in any case if the module was not yet found) try
1459 opening just the module name as passed. */
1460 if ((dir
|| (!find_handle (user_search_path
, base_name
,
1462 && !find_handle (getenv (LTDL_SEARCHPATH_VAR
), base_name
,
1464 #if defined(LT_MODULE_PATH_VAR)
1465 && !find_handle (getenv (LT_MODULE_PATH_VAR
), base_name
,
1468 #if defined(LT_DLSEARCH_PATH)
1469 && !find_handle (sys_dlsearch_path
, base_name
,
1474 if (tryall_dlopen (&newhandle
, attempt
, advise
, 0) != 0)
1489 MEMREASSIGN (*phandle
, newhandle
);
1491 if ((*phandle
)->info
.ref_count
== 0)
1493 (*phandle
)->info
.ref_count
= 1;
1494 MEMREASSIGN ((*phandle
)->info
.name
, name
);
1496 (*phandle
)->next
= handles
;
1500 LT__SETERRORSTR (saved_error
);
1506 if (!canonical
) /* was MEMREASSIGNed */
1509 FREE (archive_name
);
1515 /* If the last error message stored was `FILE_NOT_FOUND', then return
1518 file_not_found (void)
1520 const char *error
= 0;
1522 LT__GETERROR (error
);
1523 if (error
== LT__STRERROR (FILE_NOT_FOUND
))
1530 /* Unless FILENAME already bears a suitable library extension, then
1533 has_library_ext (const char *filename
)
1535 const char * ext
= 0;
1539 ext
= strrchr (filename
, '.');
1541 if (ext
&& ((streq (ext
, archive_ext
))
1542 #if defined(LT_MODULE_EXT)
1543 || (streq (ext
, shlib_ext
))
1545 #if defined(LT_SHARED_EXT)
1546 || (streq (ext
, shared_ext
))
1557 /* Initialise and configure a user lt_dladvise opaque object. */
1560 lt_dladvise_init (lt_dladvise
*padvise
)
1562 lt_dladvise advise
= (lt_dladvise
) lt__zalloc (sizeof (struct lt__advise
));
1564 return (advise
? 0 : 1);
1568 lt_dladvise_destroy (lt_dladvise
*padvise
)
1576 lt_dladvise_ext (lt_dladvise
*padvise
)
1578 assert (padvise
&& *padvise
);
1579 (*padvise
)->try_ext
= 1;
1584 lt_dladvise_resident (lt_dladvise
*padvise
)
1586 assert (padvise
&& *padvise
);
1587 (*padvise
)->is_resident
= 1;
1592 lt_dladvise_local (lt_dladvise
*padvise
)
1594 assert (padvise
&& *padvise
);
1595 (*padvise
)->is_symlocal
= 1;
1600 lt_dladvise_global (lt_dladvise
*padvise
)
1602 assert (padvise
&& *padvise
);
1603 (*padvise
)->is_symglobal
= 1;
1608 lt_dladvise_preload (lt_dladvise
*padvise
)
1610 assert (padvise
&& *padvise
);
1611 (*padvise
)->try_preload_only
= 1;
1615 /* Libtool-1.5.x interface for loading a new module named FILENAME. */
1617 lt_dlopen (const char *filename
)
1619 return lt_dlopenadvise (filename
, NULL
);
1623 /* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to
1624 open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
1625 and if a file is still not found try again with MODULE_EXT appended
1628 lt_dlopenext (const char *filename
)
1630 lt_dlhandle handle
= 0;
1633 if (!lt_dladvise_init (&advise
) && !lt_dladvise_ext (&advise
))
1634 handle
= lt_dlopenadvise (filename
, advise
);
1636 lt_dladvise_destroy (&advise
);
1642 lt_dlopenadvise (const char *filename
, lt_dladvise advise
)
1644 lt_dlhandle handle
= 0;
1646 const char * saved_error
= 0;
1648 LT__GETERROR (saved_error
);
1650 /* Can't have symbols hidden and visible at the same time! */
1651 if (advise
&& advise
->is_symlocal
&& advise
->is_symglobal
)
1653 LT__SETERROR (CONFLICTING_FLAGS
);
1660 || has_library_ext (filename
))
1662 /* Just incase we missed a code path in try_dlopen() that reports
1663 an error, but forgot to reset handle... */
1664 if (try_dlopen (&handle
, filename
, NULL
, advise
) != 0)
1669 else if (filename
&& *filename
)
1672 /* First try appending ARCHIVE_EXT. */
1673 errors
+= try_dlopen (&handle
, filename
, archive_ext
, advise
);
1675 /* If we found FILENAME, stop searching -- whether we were able to
1676 load the file as a module or not. If the file exists but loading
1677 failed, it is better to return an error message here than to
1678 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
1679 in the module search path. */
1680 if (handle
|| ((errors
> 0) && !file_not_found ()))
1683 #if defined(LT_MODULE_EXT)
1684 /* Try appending SHLIB_EXT. */
1685 LT__SETERRORSTR (saved_error
);
1686 errors
= try_dlopen (&handle
, filename
, shlib_ext
, advise
);
1688 /* As before, if the file was found but loading failed, return now
1689 with the current error message. */
1690 if (handle
|| ((errors
> 0) && !file_not_found ()))
1694 #if defined(LT_SHARED_EXT)
1695 /* Try appending SHARED_EXT. */
1696 LT__SETERRORSTR (saved_error
);
1697 errors
= try_dlopen (&handle
, filename
, shared_ext
, advise
);
1699 /* As before, if the file was found but loading failed, return now
1700 with the current error message. */
1701 if (handle
|| ((errors
> 0) && !file_not_found ()))
1706 /* Still here? Then we really did fail to locate any of the file
1708 LT__SETERROR (FILE_NOT_FOUND
);
1714 lt_argz_insert (char **pargz
, size_t *pargz_len
, char *before
,
1719 /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
1720 pargz_len, NULL, entry) failed with EINVAL. */
1722 error
= argz_insert (pargz
, pargz_len
, before
, entry
);
1724 error
= argz_append (pargz
, pargz_len
, entry
, 1 + strlen (entry
));
1731 LT__SETERROR (NO_MEMORY
);
1734 LT__SETERROR (UNKNOWN
);
1744 lt_argz_insertinorder (char **pargz
, size_t *pargz_len
, const char *entry
)
1750 assert (entry
&& *entry
);
1753 while ((before
= argz_next (*pargz
, *pargz_len
, before
)))
1755 int cmp
= strcmp (entry
, before
);
1758 if (cmp
== 0) return 0; /* No duplicates! */
1761 return lt_argz_insert (pargz
, pargz_len
, before
, entry
);
1765 lt_argz_insertdir (char **pargz
, size_t *pargz_len
, const char *dirnam
,
1771 size_t end_offset
= 0;
1779 dir_len
= LT_STRLEN (dirnam
);
1780 end
= dp
->d_name
+ D_NAMLEN(dp
);
1782 /* Ignore version numbers. */
1785 for (p
= end
; p
-1 > dp
->d_name
; --p
)
1786 if (strchr (".0123456789", p
[-1]) == 0)
1793 /* Ignore filename extension. */
1796 for (p
= end
-1; p
> dp
->d_name
; --p
)
1804 /* Prepend the directory name. */
1805 end_offset
= end
- dp
->d_name
;
1806 buf_len
= dir_len
+ 1+ end_offset
;
1807 buf
= MALLOC (char, 1+ buf_len
);
1813 strcpy (buf
, dirnam
);
1815 strncat (buf
, dp
->d_name
, end_offset
);
1816 buf
[buf_len
] = LT_EOS_CHAR
;
1818 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
1819 if (lt_argz_insertinorder (pargz
, pargz_len
, buf
) != 0)
1828 list_files_by_dir (const char *dirnam
, char **pargz
, size_t *pargz_len
)
1833 assert (dirnam
&& *dirnam
);
1836 assert (dirnam
[LT_STRLEN(dirnam
) -1] != '/');
1838 dirp
= opendir (dirnam
);
1841 struct dirent
*dp
= 0;
1843 while ((dp
= readdir (dirp
)))
1844 if (dp
->d_name
[0] != '.')
1845 if (lt_argz_insertdir (pargz
, pargz_len
, dirnam
, dp
))
1860 /* If there are any files in DIRNAME, call the function passed in
1861 DATA1 (with the name of each file and DATA2 as arguments). */
1863 foreachfile_callback (char *dirname
, void *data1
, void *data2
)
1865 file_worker_func
*func
= *(file_worker_func
**) data1
;
1869 size_t argz_len
= 0;
1871 if (list_files_by_dir (dirname
, &argz
, &argz_len
) != 0)
1878 while ((filename
= argz_next (argz
, argz_len
, filename
)))
1879 if ((is_done
= (*func
) (filename
, data2
)))
1890 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
1891 with DATA. The filenames passed to FUNC would be suitable for
1892 passing to lt_dlopenext. The extensions are stripped so that
1893 individual modules do not generate several entries (e.g. libfoo.la,
1894 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
1895 then the same directories that lt_dlopen would search are examined. */
1897 lt_dlforeachfile (const char *search_path
,
1898 int (*func
) (const char *filename
, void *data
),
1902 file_worker_func
**fpptr
= &func
;
1906 /* If a specific path was passed, search only the directories
1908 is_done
= foreach_dirinpath (search_path
, 0,
1909 foreachfile_callback
, fpptr
, data
);
1913 /* Otherwise search the default paths. */
1914 is_done
= foreach_dirinpath (user_search_path
, 0,
1915 foreachfile_callback
, fpptr
, data
);
1918 is_done
= foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR
), 0,
1919 foreachfile_callback
, fpptr
, data
);
1922 #if defined(LT_MODULE_PATH_VAR)
1925 is_done
= foreach_dirinpath (getenv(LT_MODULE_PATH_VAR
), 0,
1926 foreachfile_callback
, fpptr
, data
);
1929 #if defined(LT_DLSEARCH_PATH)
1930 if (!is_done
&& *sys_dlsearch_path
)
1932 is_done
= foreach_dirinpath (sys_dlsearch_path
, 0,
1933 foreachfile_callback
, fpptr
, data
);
1942 lt_dlclose (lt_dlhandle handle
)
1944 lt_dlhandle cur
, last
;
1947 /* check whether the handle is valid */
1948 last
= cur
= handles
;
1949 while (cur
&& handle
!= cur
)
1957 LT__SETERROR (INVALID_HANDLE
);
1963 cur
->info
.ref_count
--;
1965 /* Note that even with resident modules, we must track the ref_count
1966 correctly incase the user decides to reset the residency flag
1967 later (even though the API makes no provision for that at the
1969 if (cur
->info
.ref_count
<= 0 && !LT_DLIS_RESIDENT (cur
))
1971 lt_user_data data
= cur
->vtable
->dlloader_data
;
1975 last
->next
= cur
->next
;
1979 handles
= cur
->next
;
1982 errors
+= cur
->vtable
->module_close (data
, cur
->module
);
1983 errors
+= unload_deplibs (handle
);
1985 /* It is up to the callers to free the data itself. */
1986 FREE (cur
->interface_data
);
1988 FREE (cur
->info
.filename
);
1989 FREE (cur
->info
.name
);
1995 if (LT_DLIS_RESIDENT (handle
))
1997 LT__SETERROR (CLOSE_RESIDENT_MODULE
);
2006 lt_dlsym (lt_dlhandle place
, const char *symbol
)
2009 char lsym
[LT_SYMBOL_LENGTH
];
2017 LT__SETERROR (INVALID_HANDLE
);
2025 LT__SETERROR (SYMBOL_NOT_FOUND
);
2029 lensym
= LT_STRLEN (symbol
) + LT_STRLEN (handle
->vtable
->sym_prefix
)
2030 + LT_STRLEN (handle
->info
.name
);
2032 if (lensym
+ LT_SYMBOL_OVERHEAD
< LT_SYMBOL_LENGTH
)
2038 sym
= MALLOC (char, lensym
+ LT_SYMBOL_OVERHEAD
+ 1);
2041 LT__SETERROR (BUFFER_OVERFLOW
);
2046 data
= handle
->vtable
->dlloader_data
;
2047 if (handle
->info
.name
)
2049 const char *saved_error
;
2051 LT__GETERROR (saved_error
);
2053 /* this is a libtool module */
2054 if (handle
->vtable
->sym_prefix
)
2056 strcpy(sym
, handle
->vtable
->sym_prefix
);
2057 strcat(sym
, handle
->info
.name
);
2061 strcpy(sym
, handle
->info
.name
);
2064 strcat(sym
, "_LTX_");
2065 strcat(sym
, symbol
);
2067 /* try "modulename_LTX_symbol" */
2068 address
= handle
->vtable
->find_sym (data
, handle
->module
, sym
);
2077 LT__SETERRORSTR (saved_error
);
2080 /* otherwise try "symbol" */
2081 if (handle
->vtable
->sym_prefix
)
2083 strcpy(sym
, handle
->vtable
->sym_prefix
);
2084 strcat(sym
, symbol
);
2088 strcpy(sym
, symbol
);
2091 address
= handle
->vtable
->find_sym (data
, handle
->module
, sym
);
2105 LT__GETERROR (error
);
2106 LT__SETERRORSTR (0);
2112 lt_dlpath_insertdir (char **ppath
, char *before
, const char *dir
)
2115 char *canonical
= 0;
2117 size_t argz_len
= 0;
2120 assert (dir
&& *dir
);
2122 if (canonicalize_path (dir
, &canonical
) != 0)
2128 assert (canonical
&& *canonical
);
2130 /* If *PPATH is empty, set it to DIR. */
2133 assert (!before
); /* BEFORE cannot be set without PPATH. */
2134 assert (dir
); /* Without DIR, don't call this function! */
2136 *ppath
= lt__strdup (dir
);
2143 assert (ppath
&& *ppath
);
2145 if (argzize_path (*ppath
, &argz
, &argz_len
) != 0)
2151 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
2152 if *PPATH is already canonicalized, and hence does not change length
2153 with respect to ARGZ. We canonicalize each entry as it is added to
2154 the search path, and don't call this function with (uncanonicalized)
2155 user paths, so this is a fair assumption. */
2158 assert (*ppath
<= before
);
2159 assert ((int) (before
- *ppath
) <= (int) strlen (*ppath
));
2161 before
= before
- *ppath
+ argz
;
2164 if (lt_argz_insert (&argz
, &argz_len
, before
, dir
) != 0)
2170 argz_stringify (argz
, argz_len
, LT_PATHSEP_CHAR
);
2171 MEMREASSIGN(*ppath
, argz
);
2181 lt_dladdsearchdir (const char *search_dir
)
2185 if (search_dir
&& *search_dir
)
2187 if (lt_dlpath_insertdir (&user_search_path
, 0, search_dir
) != 0)
2195 lt_dlinsertsearchdir (const char *before
, const char *search_dir
)
2201 if ((before
< user_search_path
)
2202 || (before
>= user_search_path
+ LT_STRLEN (user_search_path
)))
2204 LT__SETERROR (INVALID_POSITION
);
2209 if (search_dir
&& *search_dir
)
2211 if (lt_dlpath_insertdir (&user_search_path
,
2212 (char *) before
, search_dir
) != 0)
2222 lt_dlsetsearchpath (const char *search_path
)
2226 FREE (user_search_path
);
2228 if (!search_path
|| !LT_STRLEN (search_path
))
2233 if (canonicalize_path (search_path
, &user_search_path
) != 0)
2240 lt_dlgetsearchpath (void)
2242 const char *saved_path
;
2244 saved_path
= user_search_path
;
2250 lt_dlmakeresident (lt_dlhandle handle
)
2256 LT__SETERROR (INVALID_HANDLE
);
2261 handle
->info
.is_resident
= 1;
2268 lt_dlisresident (lt_dlhandle handle
)
2272 LT__SETERROR (INVALID_HANDLE
);
2276 return LT_DLIS_RESIDENT (handle
);
2281 /* --- MODULE INFORMATION --- */
2284 const char *id_string
;
2285 lt_dlhandle_interface
*iface
;
2289 lt_dlinterface_register (const char *id_string
, lt_dlhandle_interface
*iface
)
2291 lt__interface_id
*interface_id
= (lt__interface_id
*) lt__malloc (sizeof *interface_id
);
2293 /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which
2294 can then be detected with lt_dlerror() if we return 0. */
2297 interface_id
->id_string
= lt__strdup (id_string
);
2298 if (!interface_id
->id_string
)
2299 FREE (interface_id
);
2301 interface_id
->iface
= iface
;
2304 return (lt_dlinterface_id
) interface_id
;
2307 void lt_dlinterface_free (lt_dlinterface_id key
)
2309 lt__interface_id
*interface_id
= (lt__interface_id
*)key
;
2310 FREE (interface_id
->id_string
);
2311 FREE (interface_id
);
2315 lt_dlcaller_set_data (lt_dlinterface_id key
, lt_dlhandle handle
, void *data
)
2318 void *stale
= (void *) 0;
2319 lt_dlhandle cur
= handle
;
2322 if (cur
->interface_data
)
2323 while (cur
->interface_data
[n_elements
].key
)
2326 for (i
= 0; i
< n_elements
; ++i
)
2328 if (cur
->interface_data
[i
].key
== key
)
2330 stale
= cur
->interface_data
[i
].data
;
2335 /* Ensure that there is enough room in this handle's interface_data
2336 array to accept a new element (and an empty end marker). */
2337 if (i
== n_elements
)
2339 lt_interface_data
*temp
2340 = REALLOC (lt_interface_data
, cur
->interface_data
, 2+ n_elements
);
2348 cur
->interface_data
= temp
;
2350 /* We only need this if we needed to allocate a new interface_data. */
2351 cur
->interface_data
[i
].key
= key
;
2352 cur
->interface_data
[1+ i
].key
= 0;
2355 cur
->interface_data
[i
].data
= data
;
2362 lt_dlcaller_get_data (lt_dlinterface_id key
, lt_dlhandle handle
)
2364 void *result
= (void *) 0;
2365 lt_dlhandle cur
= handle
;
2367 /* Locate the index of the element with a matching KEY. */
2368 if (cur
->interface_data
)
2371 for (i
= 0; cur
->interface_data
[i
].key
; ++i
)
2373 if (cur
->interface_data
[i
].key
== key
)
2375 result
= cur
->interface_data
[i
].data
;
2385 lt_dlgetinfo (lt_dlhandle handle
)
2389 LT__SETERROR (INVALID_HANDLE
);
2393 return &(handle
->info
);
2398 lt_dlhandle_iterate (lt_dlinterface_id iface
, lt_dlhandle place
)
2400 lt_dlhandle handle
= place
;
2401 lt__interface_id
*iterator
= (lt__interface_id
*) iface
;
2403 assert (iface
); /* iface is a required argument */
2408 handle
= handle
->next
;
2410 /* advance while the interface check fails */
2411 while (handle
&& iterator
->iface
2412 && ((*iterator
->iface
) (handle
, iterator
->id_string
) != 0))
2414 handle
= handle
->next
;
2422 lt_dlhandle_fetch (lt_dlinterface_id iface
, const char *module_name
)
2424 lt_dlhandle handle
= 0;
2426 assert (iface
); /* iface is a required argument */
2428 while ((handle
= lt_dlhandle_iterate (iface
, handle
)))
2430 lt_dlhandle cur
= handle
;
2431 if (cur
&& cur
->info
.name
&& streq (cur
->info
.name
, module_name
))
2440 lt_dlhandle_map (lt_dlinterface_id iface
,
2441 int (*func
) (lt_dlhandle handle
, void *data
), void *data
)
2443 lt__interface_id
*iterator
= (lt__interface_id
*) iface
;
2444 lt_dlhandle cur
= handles
;
2446 assert (iface
); /* iface is a required argument */
2452 /* advance while the interface check fails */
2453 while (cur
&& iterator
->iface
2454 && ((*iterator
->iface
) (cur
, iterator
->id_string
) != 0))
2459 if ((errorcode
= (*func
) (cur
, data
)) != 0)