1 /* ltdl.c -- system independent dlopen wrapper
3 Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006,
4 2007, 2008 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 /* This is the maximum symbol size that won't require malloc/free */
58 #undef LT_SYMBOL_LENGTH
59 #define LT_SYMBOL_LENGTH 128
61 /* This accounts for the _LTX_ separator */
62 #undef LT_SYMBOL_OVERHEAD
63 #define LT_SYMBOL_OVERHEAD 5
65 /* Various boolean flags can be stored in the flags field of an
67 #define LT_DLIS_RESIDENT(handle) ((handle)->info.is_resident)
68 #define LT_DLIS_SYMGLOBAL(handle) ((handle)->info.is_symglobal)
69 #define LT_DLIS_SYMLOCAL(handle) ((handle)->info.is_symlocal)
72 static const char objdir
[] = LT_OBJDIR
;
73 static const char archive_ext
[] = LT_ARCHIVE_EXT
;
74 static const char libext
[] = LT_LIBEXT
;
75 #if defined(LT_MODULE_EXT)
76 static const char shlib_ext
[] = LT_MODULE_EXT
;
78 #if defined(LT_DLSEARCH_PATH)
79 static const char sys_dlsearch_path
[] = LT_DLSEARCH_PATH
;
85 /* --- DYNAMIC MODULE LOADING --- */
88 /* The type of a function used at each iteration of foreach_dirinpath(). */
89 typedef int foreach_callback_func (char *filename
, void *data1
,
91 /* foreachfile_callback itself calls a function of this type: */
92 typedef int file_worker_func (const char *filename
, void *data
);
95 static int foreach_dirinpath (const char *search_path
,
96 const char *base_name
,
97 foreach_callback_func
*func
,
98 void *data1
, void *data2
);
99 static int find_file_callback (char *filename
, void *data1
,
101 static int find_handle_callback (char *filename
, void *data
,
103 static int foreachfile_callback (char *filename
, void *data1
,
107 static int canonicalize_path (const char *path
, char **pcanonical
);
108 static int argzize_path (const char *path
,
109 char **pargz
, size_t *pargz_len
);
110 static FILE *find_file (const char *search_path
,
111 const char *base_name
, char **pdir
);
112 static lt_dlhandle
*find_handle (const char *search_path
,
113 const char *base_name
,
116 static int find_module (lt_dlhandle
*handle
, const char *dir
,
117 const char *libdir
, const char *dlname
,
118 const char *old_name
, int installed
,
120 static int has_library_ext (const char *filename
);
121 static int load_deplibs (lt_dlhandle handle
, char *deplibs
);
122 static int trim (char **dest
, const char *str
);
123 static int try_dlopen (lt_dlhandle
*handle
,
124 const char *filename
, const char *ext
,
126 static int tryall_dlopen (lt_dlhandle
*handle
,
127 const char *filename
,
129 const lt_dlvtable
*vtable
);
130 static int unload_deplibs (lt_dlhandle handle
);
131 static int lt_argz_insert (char **pargz
, size_t *pargz_len
,
132 char *before
, const char *entry
);
133 static int lt_argz_insertinorder (char **pargz
, size_t *pargz_len
,
135 static int lt_argz_insertdir (char **pargz
, size_t *pargz_len
,
136 const char *dirnam
, struct dirent
*dp
);
137 static int lt_dlpath_insertdir (char **ppath
, char *before
,
139 static int list_files_by_dir (const char *dirnam
,
140 char **pargz
, size_t *pargz_len
);
141 static int file_not_found (void);
143 #ifdef HAVE_LIBDLLOADER
144 static int loader_init_callback (lt_dlhandle handle
);
145 #endif /* HAVE_LIBDLLOADER */
147 static int loader_init (lt_get_vtable
*vtable_func
,
150 static char *user_search_path
= 0;
151 static lt_dlhandle handles
= 0;
152 static int initialized
= 0;
154 /* Our memory failure callback sets the error message to be passed back
155 up to the client, so we must be careful to return from mallocation
156 callers if allocation fails (as this callback returns!!). */
158 lt__alloc_die_callback (void)
160 LT__SETERROR (NO_MEMORY
);
163 #ifdef HAVE_LIBDLLOADER
164 /* This function is called to initialise each preloaded module loader,
165 and hook it into the list of loaders to be used when attempting to
166 dlopen an application module. */
168 loader_init_callback (lt_dlhandle handle
)
170 lt_get_vtable
*vtable_func
= (lt_get_vtable
*) lt_dlsym (handle
, "get_vtable");
171 return loader_init (vtable_func
, 0);
173 #endif /* HAVE_LIBDLLOADER */
176 loader_init (lt_get_vtable
*vtable_func
, lt_user_data data
)
178 const lt_dlvtable
*vtable
= 0;
183 vtable
= (*vtable_func
) (data
);
186 /* lt_dlloader_add will LT__SETERROR if it fails. */
187 errors
+= lt_dlloader_add (vtable
);
189 assert (errors
|| vtable
);
191 if ((!errors
) && vtable
->dlloader_init
)
193 if ((*vtable
->dlloader_init
) (vtable
->dlloader_data
))
195 LT__SETERROR (INIT_LOADER
);
203 /* Bootstrap the loader loading with the preopening loader. */
204 #define get_vtable preopen_LTX_get_vtable
205 #define preloaded_symbols LT_CONC3(lt_, LTDLOPEN, _LTX_preloaded_symbols)
208 LT_SCOPE
const lt_dlvtable
* get_vtable (lt_user_data data
);
210 #ifdef HAVE_LIBDLLOADER
211 extern lt_dlsymlist preloaded_symbols
;
214 /* Initialize libltdl. */
220 /* Initialize only at first call. */
221 if (++initialized
== 1)
223 lt__alloc_die
= lt__alloc_die_callback
;
225 user_search_path
= 0; /* empty search path */
227 /* First set up the statically loaded preload module loader, so
228 we can use it to preopen the other loaders we linked in at
230 errors
+= loader_init (get_vtable
, 0);
232 /* Now open all the preloaded module loaders, so the application
233 can use _them_ to lt_dlopen its own modules. */
234 #ifdef HAVE_LIBDLLOADER
237 errors
+= lt_dlpreload (&preloaded_symbols
);
242 errors
+= lt_dlpreload_open (LT_STR(LTDLOPEN
), loader_init_callback
);
244 #endif /* HAVE_LIBDLLOADER */
247 #ifdef LT_DEBUG_LOADERS
257 /* shut down libltdl */
258 lt_dlloader
*loader
= 0;
259 lt_dlhandle handle
= handles
;
264 LT__SETERROR (SHUTDOWN
);
269 /* shut down only at last call. */
270 if (--initialized
== 0)
274 while (handles
&& LT_DLIS_RESIDENT (handles
))
276 handles
= handles
->next
;
279 /* close all modules */
280 for (level
= 1; handle
; ++level
)
282 lt_dlhandle cur
= handles
;
283 int saw_nonresident
= 0;
287 lt_dlhandle tmp
= cur
;
289 if (!LT_DLIS_RESIDENT (tmp
))
292 if (tmp
->info
.ref_count
<= level
)
294 if (lt_dlclose (tmp
))
298 /* Make sure that the handle pointed to by 'cur' still exists.
299 lt_dlclose recursively closes dependent libraries which removes
300 them from the linked list. One of these might be the one
301 pointed to by 'cur'. */
304 for (tmp
= handles
; tmp
; tmp
= tmp
->next
)
313 /* done if only resident modules are left */
314 if (!saw_nonresident
)
318 /* When removing loaders, we can only find out failure by testing
319 the error string, so avoid a spurious one from an earlier
324 /* close all loaders */
325 for (loader
= (lt_dlloader
*) lt_dlloader_next (NULL
); loader
;)
327 lt_dlloader
*next
= (lt_dlloader
*) lt_dlloader_next (loader
);
328 lt_dlvtable
*vtable
= (lt_dlvtable
*) lt_dlloader_get (loader
);
330 if ((vtable
= lt_dlloader_remove ((char *) vtable
->name
)))
336 /* ignore errors due to resident modules */
346 FREE(user_search_path
);
354 /* Try VTABLE or, if VTABLE is NULL, all available loaders for FILENAME.
355 If the library is not successfully loaded, return non-zero. Otherwise,
356 the dlhandle is stored at the address given in PHANDLE. */
358 tryall_dlopen (lt_dlhandle
*phandle
, const char *filename
,
359 lt_dladvise advise
, const lt_dlvtable
*vtable
)
361 lt_dlhandle handle
= handles
;
362 const char * saved_error
= 0;
365 #ifdef LT_DEBUG_LOADERS
366 fprintf (stderr
, "tryall_dlopen (%s, %s)\n",
367 filename
? filename
: "(null)",
368 vtable
? vtable
->name
: "(ALL)");
371 LT__GETERROR (saved_error
);
373 /* check whether the module was already opened */
374 for (;handle
; handle
= handle
->next
)
376 if ((handle
->info
.filename
== filename
) /* dlopen self: 0 == 0 */
377 || (handle
->info
.filename
&& filename
378 && streq (handle
->info
.filename
, filename
)))
386 ++handle
->info
.ref_count
;
394 /* Comment out the check of file permissions using access.
395 This call seems to always return -1 with error EACCES.
397 /* We need to catch missing file errors early so that
398 file_not_found() can detect what happened.
399 if (access (filename, R_OK) != 0)
401 LT__SETERROR (FILE_NOT_FOUND);
406 handle
->info
.filename
= lt__strdup (filename
);
407 if (!handle
->info
.filename
)
415 handle
->info
.filename
= 0;
419 lt_dlloader loader
= lt_dlloader_next (0);
420 const lt_dlvtable
*loader_vtable
;
425 loader_vtable
= vtable
;
427 loader_vtable
= lt_dlloader_get (loader
);
429 #ifdef LT_DEBUG_LOADERS
430 fprintf (stderr
, "Calling %s->module_open (%s)\n",
431 (loader_vtable
&& loader_vtable
->name
) ? loader_vtable
->name
: "(null)",
432 filename
? filename
: "(null)");
434 handle
->module
= (*loader_vtable
->module_open
) (loader_vtable
->dlloader_data
,
436 #ifdef LT_DEBUG_LOADERS
437 fprintf (stderr
, " Result: %s\n",
438 handle
->module
? "Success" : "Failed");
441 if (handle
->module
!= 0)
445 handle
->info
.is_resident
= advise
->is_resident
;
446 handle
->info
.is_symglobal
= advise
->is_symglobal
;
447 handle
->info
.is_symlocal
= advise
->is_symlocal
;
452 while (!vtable
&& (loader
= lt_dlloader_next (loader
)));
454 /* If VTABLE was given but couldn't open the module, or VTABLE wasn't
455 given but we exhausted all loaders without opening the module, bail
457 if ((vtable
&& !handle
->module
)
458 || (!vtable
&& !loader
))
460 FREE (handle
->info
.filename
);
465 handle
->vtable
= loader_vtable
;
468 LT__SETERRORSTR (saved_error
);
476 tryall_dlopen_module (lt_dlhandle
*handle
, const char *prefix
,
477 const char *dirname
, const char *dlname
,
482 size_t filename_len
= 0;
483 size_t dirname_len
= LT_STRLEN (dirname
);
488 #if defined(LT_DIRSEP_CHAR)
489 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
490 should make it into this function: */
491 assert (strchr (dirname
, LT_DIRSEP_CHAR
) == 0);
495 if (dirname
[dirname_len
-1] == '/')
497 filename_len
= dirname_len
+ 1 + LT_STRLEN (dlname
);
499 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
500 The PREFIX (if any) is handled below. */
501 filename
= MALLOC (char, filename_len
+ 1);
505 sprintf (filename
, "%.*s/%s", (int) dirname_len
, dirname
, dlname
);
507 /* Now that we have combined DIRNAME and MODULENAME, if there is
508 also a PREFIX to contend with, simply recurse with the arguments
509 shuffled. Otherwise, attempt to open FILENAME as a module. */
512 error
+= tryall_dlopen_module (handle
, (const char *) 0,
513 prefix
, filename
, advise
);
515 else if (tryall_dlopen (handle
, filename
, advise
, 0) != 0)
525 find_module (lt_dlhandle
*handle
, const char *dir
, const char *libdir
,
526 const char *dlname
, const char *old_name
, int installed
,
529 /* Try to open the old library first; if it was dlpreopened,
530 we want the preopened version of it, even if a dlopenable
531 module is available. */
532 if (old_name
&& tryall_dlopen (handle
, old_name
, advise
, 0) == 0)
537 /* Try to open the dynamic library. */
540 /* try to open the installed module */
541 if (installed
&& libdir
)
543 if (tryall_dlopen_module (handle
, (const char *) 0,
544 libdir
, dlname
, advise
) == 0)
548 /* try to open the not-installed module */
551 if (tryall_dlopen_module (handle
, dir
, objdir
,
552 dlname
, advise
) == 0)
556 /* maybe it was moved to another directory */
558 if (dir
&& (tryall_dlopen_module (handle
, (const char *) 0,
559 dir
, dlname
, advise
) == 0))
569 canonicalize_path (const char *path
, char **pcanonical
)
573 assert (path
&& *path
);
576 canonical
= MALLOC (char, 1+ LT_STRLEN (path
));
583 for (src
= 0; path
[src
] != LT_EOS_CHAR
; ++src
)
585 /* Path separators are not copied to the beginning or end of
586 the destination, or if another separator would follow
588 if (path
[src
] == LT_PATHSEP_CHAR
)
591 || (path
[1+ src
] == LT_PATHSEP_CHAR
)
592 || (path
[1+ src
] == LT_EOS_CHAR
))
596 /* Anything other than a directory separator is copied verbatim. */
597 if ((path
[src
] != '/')
598 #if defined(LT_DIRSEP_CHAR)
599 && (path
[src
] != LT_DIRSEP_CHAR
)
603 canonical
[dest
++] = path
[src
];
605 /* Directory separators are converted and copied only if they are
606 not at the end of a path -- i.e. before a path separator or
608 else if ((path
[1+ src
] != LT_PATHSEP_CHAR
)
609 && (path
[1+ src
] != LT_EOS_CHAR
)
610 #if defined(LT_DIRSEP_CHAR)
611 && (path
[1+ src
] != LT_DIRSEP_CHAR
)
613 && (path
[1+ src
] != '/'))
615 canonical
[dest
++] = '/';
619 /* Add an end-of-string marker at the end. */
620 canonical
[dest
] = LT_EOS_CHAR
;
623 /* Assign new value. */
624 *pcanonical
= canonical
;
630 argzize_path (const char *path
, char **pargz
, size_t *pargz_len
)
638 if ((error
= argz_create_sep (path
, LT_PATHSEP_CHAR
, pargz
, pargz_len
)))
643 LT__SETERROR (NO_MEMORY
);
646 LT__SETERROR (UNKNOWN
);
656 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
657 of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
658 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
659 it is appended to each SEARCH_PATH element before FUNC is called. */
661 foreach_dirinpath (const char *search_path
, const char *base_name
,
662 foreach_callback_func
*func
, void *data1
, void *data2
)
665 size_t filenamesize
= 0;
666 size_t lenbase
= LT_STRLEN (base_name
);
672 if (!search_path
|| !*search_path
)
674 LT__SETERROR (FILE_NOT_FOUND
);
678 if (canonicalize_path (search_path
, &canonical
) != 0)
681 if (argzize_path (canonical
, &argz
, &argz_len
) != 0)
686 while ((dir_name
= argz_next (argz
, argz_len
, dir_name
)))
688 size_t lendir
= LT_STRLEN (dir_name
);
690 if (1+ lendir
+ lenbase
>= filenamesize
)
693 filenamesize
= 1+ lendir
+ 1+ lenbase
; /* "/d" + '/' + "f" + '\0' */
694 filename
= MALLOC (char, filenamesize
);
699 assert (filenamesize
> lendir
);
700 strcpy (filename
, dir_name
);
702 if (base_name
&& *base_name
)
704 if (filename
[lendir
-1] != '/')
705 filename
[lendir
++] = '/';
706 strcpy (filename
+lendir
, base_name
);
709 if ((result
= (*func
) (filename
, data1
, data2
)))
724 /* If FILEPATH can be opened, store the name of the directory component
725 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
726 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
728 find_file_callback (char *filename
, void *data1
, void *data2
)
730 char **pdir
= (char **) data1
;
731 FILE **pfile
= (FILE **) data2
;
734 assert (filename
&& *filename
);
738 if ((*pfile
= fopen (filename
, LT_READTEXT_MODE
)))
740 char *dirend
= strrchr (filename
, '/');
742 if (dirend
> filename
)
743 *dirend
= LT_EOS_CHAR
;
746 *pdir
= lt__strdup (filename
);
747 is_done
= (*pdir
== 0) ? -1 : 1;
754 find_file (const char *search_path
, const char *base_name
, char **pdir
)
758 foreach_dirinpath (search_path
, base_name
, find_file_callback
, pdir
, &file
);
764 find_handle_callback (char *filename
, void *data
, void *data2
)
766 lt_dlhandle
*phandle
= (lt_dlhandle
*) data
;
767 int notfound
= access (filename
, R_OK
);
768 lt_dladvise advise
= (lt_dladvise
) data2
;
770 /* Bail out if file cannot be read... */
774 /* Try to dlopen the file, but do not continue searching in any
776 if (tryall_dlopen (phandle
, filename
, advise
, 0) != 0)
782 /* If HANDLE was found return it, otherwise return 0. If HANDLE was
783 found but could not be opened, *HANDLE will be set to 0. */
785 find_handle (const char *search_path
, const char *base_name
,
786 lt_dlhandle
*phandle
, lt_dladvise advise
)
791 if (!foreach_dirinpath (search_path
, base_name
, find_handle_callback
,
798 #if !defined(LTDL_DLOPEN_DEPLIBS)
800 load_deplibs (lt_dlhandle handle
, char * LT__UNUSED deplibs
)
802 handle
->depcount
= 0;
806 #else /* defined(LTDL_DLOPEN_DEPLIBS) */
808 load_deplibs (lt_dlhandle handle
, char *deplibs
)
810 char *p
, *save_search_path
= 0;
816 handle
->depcount
= 0;
824 if (user_search_path
)
826 save_search_path
= lt__strdup (user_search_path
);
827 if (!save_search_path
)
831 /* extract search paths and count deplibs */
835 if (!isspace ((unsigned char) *p
))
838 while (*end
&& !isspace((unsigned char) *end
))
843 if (strncmp(p
, "-L", 2) == 0 || strncmp(p
, "-R", 2) == 0)
846 *end
= 0; /* set a temporary string terminator */
847 if (lt_dladdsearchdir(p
+2))
873 names
= MALLOC (char *, depcount
);
877 /* now only extract the actual deplibs */
882 if (isspace ((unsigned char) *p
))
889 while (*end
&& !isspace ((unsigned char) *end
))
894 if (strncmp(p
, "-L", 2) != 0 && strncmp(p
, "-R", 2) != 0)
898 *end
= 0; /* set a temporary string terminator */
899 if (strncmp(p
, "-l", 2) == 0)
901 size_t name_len
= 3+ /* "lib" */ LT_STRLEN (p
+ 2);
902 name
= MALLOC (char, 1+ name_len
);
904 sprintf (name
, "lib%s", p
+2);
907 name
= lt__strdup(p
);
912 names
[depcount
++] = name
;
919 /* load the deplibs (in reverse order)
920 At this stage, don't worry if the deplibs do not load correctly,
921 they may already be statically linked into the loading application
922 for instance. There will be a more enlightening error message
923 later on if the loaded module cannot resolve all of its symbols. */
926 lt_dlhandle cur
= handle
;
929 cur
->deplibs
= MALLOC (lt_dlhandle
, depcount
);
933 for (i
= 0; i
< depcount
; ++i
)
935 cur
->deplibs
[j
] = lt_dlopenext(names
[depcount
-1-i
]);
942 cur
->depcount
= j
; /* Number of successfully loaded deplibs */
947 for (i
= 0; i
< depcount
; ++i
)
954 /* restore the old search path */
955 if (save_search_path
) {
956 MEMREASSIGN (user_search_path
, save_search_path
);
961 #endif /* defined(LTDL_DLOPEN_DEPLIBS) */
964 unload_deplibs (lt_dlhandle handle
)
968 lt_dlhandle cur
= handle
;
972 for (i
= 0; i
< cur
->depcount
; ++i
)
974 if (!LT_DLIS_RESIDENT (cur
->deplibs
[i
]))
976 errors
+= lt_dlclose (cur
->deplibs
[i
]);
986 trim (char **dest
, const char *str
)
988 /* remove the leading and trailing "'" from str
989 and store the result in dest */
990 const char *end
= strrchr (str
, '\'');
991 size_t len
= LT_STRLEN (str
);
999 if (len
> 3 && str
[0] == '\'')
1001 tmp
= MALLOC (char, end
- str
);
1005 memcpy(tmp
, &str
[1], (end
- str
) - 1);
1006 tmp
[(end
- str
) - 1] = LT_EOS_CHAR
;
1017 /* Read the .la file FILE. */
1019 parse_dotla_file(FILE *file
, char **dlname
, char **libdir
, char **deplibs
,
1020 char **old_name
, int *installed
)
1023 size_t line_len
= LT_FILENAME_MAX
;
1024 char * line
= MALLOC (char, line_len
);
1028 LT__SETERROR (FILE_NOT_FOUND
);
1032 while (!feof (file
))
1034 line
[line_len
-2] = '\0';
1035 if (!fgets (line
, (int) line_len
, file
))
1040 /* Handle the case where we occasionally need to read a line
1041 that is longer than the initial buffer size.
1042 Behave even if the file contains NUL bytes due to corruption. */
1043 while (line
[line_len
-2] != '\0' && line
[line_len
-2] != '\n' && !feof (file
))
1045 line
= REALLOC (char, line
, line_len
*2);
1051 line
[line_len
* 2 - 2] = '\0';
1052 if (!fgets (&line
[line_len
-1], (int) line_len
+1, file
))
1059 if (line
[0] == '\n' || line
[0] == '#')
1065 #define STR_DLNAME "dlname="
1066 if (strncmp (line
, STR_DLNAME
, sizeof (STR_DLNAME
) - 1) == 0)
1068 errors
+= trim (dlname
, &line
[sizeof (STR_DLNAME
) - 1]);
1071 #undef STR_OLD_LIBRARY
1072 #define STR_OLD_LIBRARY "old_library="
1073 else if (strncmp (line
, STR_OLD_LIBRARY
,
1074 sizeof (STR_OLD_LIBRARY
) - 1) == 0)
1076 errors
+= trim (old_name
, &line
[sizeof (STR_OLD_LIBRARY
) - 1]);
1079 #define STR_LIBDIR "libdir="
1080 else if (strncmp (line
, STR_LIBDIR
, sizeof (STR_LIBDIR
) - 1) == 0)
1082 errors
+= trim (libdir
, &line
[sizeof(STR_LIBDIR
) - 1]);
1085 #undef STR_DL_DEPLIBS
1086 #define STR_DL_DEPLIBS "dependency_libs="
1087 else if (strncmp (line
, STR_DL_DEPLIBS
,
1088 sizeof (STR_DL_DEPLIBS
) - 1) == 0)
1090 errors
+= trim (deplibs
, &line
[sizeof (STR_DL_DEPLIBS
) - 1]);
1092 else if (streq (line
, "installed=yes\n"))
1096 else if (streq (line
, "installed=no\n"))
1101 #undef STR_LIBRARY_NAMES
1102 #define STR_LIBRARY_NAMES "library_names="
1103 else if (!*dlname
&& strncmp (line
, STR_LIBRARY_NAMES
,
1104 sizeof (STR_LIBRARY_NAMES
) - 1) == 0)
1107 errors
+= trim (dlname
, &line
[sizeof (STR_LIBRARY_NAMES
) - 1]);
1110 && (last_libname
= strrchr (*dlname
, ' ')) != 0)
1112 last_libname
= lt__strdup (last_libname
+ 1);
1118 MEMREASSIGN (*dlname
, last_libname
);
1131 /* Try to open FILENAME as a module. */
1133 try_dlopen (lt_dlhandle
*phandle
, const char *filename
, const char *ext
,
1136 const char * saved_error
= 0;
1137 char * archive_name
= 0;
1138 char * canonical
= 0;
1139 char * base_name
= 0;
1144 lt_dlhandle newhandle
;
1147 assert (*phandle
== 0);
1149 #ifdef LT_DEBUG_LOADERS
1150 fprintf (stderr
, "try_dlopen (%s, %s)\n",
1151 filename
? filename
: "(null)",
1152 ext
? ext
: "(null)");
1155 LT__GETERROR (saved_error
);
1160 *phandle
= (lt_dlhandle
) lt__zalloc (sizeof (struct lt__handle
));
1164 newhandle
= *phandle
;
1166 /* lt_dlclose()ing yourself is very bad! Disallow it. */
1167 newhandle
->info
.is_resident
= 1;
1169 if (tryall_dlopen (&newhandle
, 0, advise
, 0) != 0)
1175 goto register_handle
;
1178 assert (filename
&& *filename
);
1182 attempt
= MALLOC (char, LT_STRLEN (filename
) + LT_STRLEN (ext
) + 1);
1186 sprintf(attempt
, "%s%s", filename
, ext
);
1190 attempt
= lt__strdup (filename
);
1195 /* Doing this immediately allows internal functions to safely
1196 assume only canonicalized paths are passed. */
1197 if (canonicalize_path (attempt
, &canonical
) != 0)
1203 /* If the canonical module name is a path (relative or absolute)
1204 then split it into a directory part and a name part. */
1205 base_name
= strrchr (canonical
, '/');
1208 size_t dirlen
= (1+ base_name
) - canonical
;
1210 dir
= MALLOC (char, 1+ dirlen
);
1217 strncpy (dir
, canonical
, dirlen
);
1218 dir
[dirlen
] = LT_EOS_CHAR
;
1223 MEMREASSIGN (base_name
, canonical
);
1225 assert (base_name
&& *base_name
);
1227 ext
= strrchr (base_name
, '.');
1230 ext
= base_name
+ LT_STRLEN (base_name
);
1233 /* extract the module name from the file name */
1234 name
= MALLOC (char, ext
- base_name
+ 1);
1241 /* canonicalize the module name */
1244 for (i
= 0; i
< ext
- base_name
; ++i
)
1246 if (isalnum ((unsigned char)(base_name
[i
])))
1248 name
[i
] = base_name
[i
];
1255 name
[ext
- base_name
] = LT_EOS_CHAR
;
1258 /* Before trawling through the filesystem in search of a module,
1259 check whether we are opening a preloaded module. */
1262 const lt_dlvtable
*vtable
= lt_dlloader_find ("lt_preopen");
1266 /* name + "." + libext + NULL */
1267 archive_name
= MALLOC (char, LT_STRLEN (name
) + LT_STRLEN (libext
) + 2);
1268 *phandle
= (lt_dlhandle
) lt__zalloc (sizeof (struct lt__handle
));
1270 if ((*phandle
== NULL
) || (archive_name
== NULL
))
1275 newhandle
= *phandle
;
1277 /* Preloaded modules are always named according to their old
1279 sprintf (archive_name
, "%s.%s", name
, libext
);
1281 if (tryall_dlopen (&newhandle
, archive_name
, advise
, vtable
) == 0)
1283 goto register_handle
;
1286 /* If we're still here, there was no matching preloaded module,
1287 so put things back as we found them, and continue searching. */
1293 /* If we are allowing only preloaded modules, and we didn't find
1294 anything yet, give up on the search here. */
1295 if (advise
&& advise
->try_preload_only
)
1300 /* Check whether we are opening a libtool module (.la extension). */
1301 if (ext
&& streq (ext
, archive_ext
))
1303 /* this seems to be a libtool module */
1306 char * old_name
= 0;
1310 /* if we can't find the installed flag, it is probably an
1311 installed libtool archive, produced with an old version
1315 /* Now try to open the .la file. If there is no directory name
1316 component, try to find it first in user_search_path and then other
1317 prescribed paths. Otherwise (or in any case if the module was not
1318 yet found) try opening just the module name as passed. */
1321 const char *search_path
= user_search_path
;
1324 file
= find_file (user_search_path
, base_name
, &dir
);
1328 search_path
= getenv (LTDL_SEARCHPATH_VAR
);
1330 file
= find_file (search_path
, base_name
, &dir
);
1333 #if defined(LT_MODULE_PATH_VAR)
1336 search_path
= getenv (LT_MODULE_PATH_VAR
);
1338 file
= find_file (search_path
, base_name
, &dir
);
1341 #if defined(LT_DLSEARCH_PATH)
1342 if (!file
&& *sys_dlsearch_path
)
1344 file
= find_file (sys_dlsearch_path
, base_name
, &dir
);
1350 file
= fopen (attempt
, LT_READTEXT_MODE
);
1353 /* If we didn't find the file by now, it really isn't there. Set
1354 the status flag, and bail out. */
1357 LT__SETERROR (FILE_NOT_FOUND
);
1362 /* read the .la file */
1363 if (parse_dotla_file(file
, &dlname
, &libdir
, &deplibs
,
1364 &old_name
, &installed
) != 0)
1369 /* allocate the handle */
1370 *phandle
= (lt_dlhandle
) lt__zalloc (sizeof (struct lt__handle
));
1386 if (load_deplibs (*phandle
, deplibs
) == 0)
1388 newhandle
= *phandle
;
1389 /* find_module may replace newhandle */
1390 if (find_module (&newhandle
, dir
, libdir
, dlname
, old_name
,
1393 unload_deplibs (*phandle
);
1413 if (*phandle
!= newhandle
)
1415 unload_deplibs (*phandle
);
1420 /* not a libtool module */
1421 *phandle
= (lt_dlhandle
) lt__zalloc (sizeof (struct lt__handle
));
1428 newhandle
= *phandle
;
1430 /* If the module has no directory name component, try to find it
1431 first in user_search_path and then other prescribed paths.
1432 Otherwise (or in any case if the module was not yet found) try
1433 opening just the module name as passed. */
1434 if ((dir
|| (!find_handle (user_search_path
, base_name
,
1436 && !find_handle (getenv (LTDL_SEARCHPATH_VAR
), base_name
,
1438 #if defined(LT_MODULE_PATH_VAR)
1439 && !find_handle (getenv (LT_MODULE_PATH_VAR
), base_name
,
1442 #if defined(LT_DLSEARCH_PATH)
1443 && !find_handle (sys_dlsearch_path
, base_name
,
1448 if (tryall_dlopen (&newhandle
, attempt
, advise
, 0) != 0)
1463 MEMREASSIGN (*phandle
, newhandle
);
1465 if ((*phandle
)->info
.ref_count
== 0)
1467 (*phandle
)->info
.ref_count
= 1;
1468 MEMREASSIGN ((*phandle
)->info
.name
, name
);
1470 (*phandle
)->next
= handles
;
1474 LT__SETERRORSTR (saved_error
);
1480 if (!canonical
) /* was MEMREASSIGNed */
1483 FREE (archive_name
);
1489 /* If the last error messge store was `FILE_NOT_FOUND', then return
1492 file_not_found (void)
1494 const char *error
= 0;
1496 LT__GETERROR (error
);
1497 if (error
== LT__STRERROR (FILE_NOT_FOUND
))
1504 /* Unless FILENAME already bears a suitable library extension, then
1507 has_library_ext (const char *filename
)
1513 ext
= strrchr (filename
, '.');
1515 if (ext
&& ((streq (ext
, archive_ext
))
1516 #if defined(LT_MODULE_EXT)
1517 || (streq (ext
, shlib_ext
))
1528 /* Initialise and configure a user lt_dladvise opaque object. */
1531 lt_dladvise_init (lt_dladvise
*padvise
)
1533 lt_dladvise advise
= (lt_dladvise
) lt__zalloc (sizeof (struct lt__advise
));
1535 return (advise
? 0 : 1);
1539 lt_dladvise_destroy (lt_dladvise
*padvise
)
1547 lt_dladvise_ext (lt_dladvise
*padvise
)
1549 assert (padvise
&& *padvise
);
1550 (*padvise
)->try_ext
= 1;
1555 lt_dladvise_resident (lt_dladvise
*padvise
)
1557 assert (padvise
&& *padvise
);
1558 (*padvise
)->is_resident
= 1;
1563 lt_dladvise_local (lt_dladvise
*padvise
)
1565 assert (padvise
&& *padvise
);
1566 (*padvise
)->is_symlocal
= 1;
1571 lt_dladvise_global (lt_dladvise
*padvise
)
1573 assert (padvise
&& *padvise
);
1574 (*padvise
)->is_symglobal
= 1;
1579 lt_dladvise_preload (lt_dladvise
*padvise
)
1581 assert (padvise
&& *padvise
);
1582 (*padvise
)->try_preload_only
= 1;
1586 /* Libtool-1.5.x interface for loading a new module named FILENAME. */
1588 lt_dlopen (const char *filename
)
1590 return lt_dlopenadvise (filename
, NULL
);
1594 /* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to
1595 open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
1596 and if a file is still not found try again with MODULE_EXT appended
1599 lt_dlopenext (const char *filename
)
1601 lt_dlhandle handle
= 0;
1604 if (!lt_dladvise_init (&advise
) && !lt_dladvise_ext (&advise
))
1605 handle
= lt_dlopenadvise (filename
, advise
);
1607 lt_dladvise_destroy (&advise
);
1613 lt_dlopenadvise (const char *filename
, lt_dladvise advise
)
1615 lt_dlhandle handle
= 0;
1618 /* Can't have symbols hidden and visible at the same time! */
1619 if (advise
&& advise
->is_symlocal
&& advise
->is_symglobal
)
1621 LT__SETERROR (CONFLICTING_FLAGS
);
1628 || has_library_ext (filename
))
1630 /* Just incase we missed a code path in try_dlopen() that reports
1631 an error, but forgot to reset handle... */
1632 if (try_dlopen (&handle
, filename
, NULL
, advise
) != 0)
1637 else if (filename
&& *filename
)
1640 /* First try appending ARCHIVE_EXT. */
1641 errors
+= try_dlopen (&handle
, filename
, archive_ext
, advise
);
1643 /* If we found FILENAME, stop searching -- whether we were able to
1644 load the file as a module or not. If the file exists but loading
1645 failed, it is better to return an error message here than to
1646 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
1647 in the module search path. */
1648 if (handle
|| ((errors
> 0) && !file_not_found ()))
1651 #if defined(LT_MODULE_EXT)
1652 /* Try appending SHLIB_EXT. */
1653 errors
= try_dlopen (&handle
, filename
, shlib_ext
, advise
);
1655 /* As before, if the file was found but loading failed, return now
1656 with the current error message. */
1657 if (handle
|| ((errors
> 0) && !file_not_found ()))
1662 /* Still here? Then we really did fail to locate any of the file
1664 LT__SETERROR (FILE_NOT_FOUND
);
1670 lt_argz_insert (char **pargz
, size_t *pargz_len
, char *before
,
1675 /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
1676 pargz_len, NULL, entry) failed with EINVAL. */
1678 error
= argz_insert (pargz
, pargz_len
, before
, entry
);
1680 error
= argz_append (pargz
, pargz_len
, entry
, 1 + strlen (entry
));
1687 LT__SETERROR (NO_MEMORY
);
1690 LT__SETERROR (UNKNOWN
);
1700 lt_argz_insertinorder (char **pargz
, size_t *pargz_len
, const char *entry
)
1706 assert (entry
&& *entry
);
1709 while ((before
= argz_next (*pargz
, *pargz_len
, before
)))
1711 int cmp
= strcmp (entry
, before
);
1714 if (cmp
== 0) return 0; /* No duplicates! */
1717 return lt_argz_insert (pargz
, pargz_len
, before
, entry
);
1721 lt_argz_insertdir (char **pargz
, size_t *pargz_len
, const char *dirnam
,
1727 size_t end_offset
= 0;
1735 dir_len
= LT_STRLEN (dirnam
);
1736 end
= dp
->d_name
+ D_NAMLEN(dp
);
1738 /* Ignore version numbers. */
1741 for (p
= end
; p
-1 > dp
->d_name
; --p
)
1742 if (strchr (".0123456789", p
[-1]) == 0)
1749 /* Ignore filename extension. */
1752 for (p
= end
-1; p
> dp
->d_name
; --p
)
1760 /* Prepend the directory name. */
1761 end_offset
= end
- dp
->d_name
;
1762 buf_len
= dir_len
+ 1+ end_offset
;
1763 buf
= MALLOC (char, 1+ buf_len
);
1769 strcpy (buf
, dirnam
);
1771 strncat (buf
, dp
->d_name
, end_offset
);
1772 buf
[buf_len
] = LT_EOS_CHAR
;
1774 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
1775 if (lt_argz_insertinorder (pargz
, pargz_len
, buf
) != 0)
1784 list_files_by_dir (const char *dirnam
, char **pargz
, size_t *pargz_len
)
1789 assert (dirnam
&& *dirnam
);
1792 assert (dirnam
[LT_STRLEN(dirnam
) -1] != '/');
1794 dirp
= opendir (dirnam
);
1797 struct dirent
*dp
= 0;
1799 while ((dp
= readdir (dirp
)))
1800 if (dp
->d_name
[0] != '.')
1801 if (lt_argz_insertdir (pargz
, pargz_len
, dirnam
, dp
))
1816 /* If there are any files in DIRNAME, call the function passed in
1817 DATA1 (with the name of each file and DATA2 as arguments). */
1819 foreachfile_callback (char *dirname
, void *data1
, void *data2
)
1821 file_worker_func
*func
= *(file_worker_func
**) data1
;
1825 size_t argz_len
= 0;
1827 if (list_files_by_dir (dirname
, &argz
, &argz_len
) != 0)
1834 while ((filename
= argz_next (argz
, argz_len
, filename
)))
1835 if ((is_done
= (*func
) (filename
, data2
)))
1846 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
1847 with DATA. The filenames passed to FUNC would be suitable for
1848 passing to lt_dlopenext. The extensions are stripped so that
1849 individual modules do not generate several entries (e.g. libfoo.la,
1850 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
1851 then the same directories that lt_dlopen would search are examined. */
1853 lt_dlforeachfile (const char *search_path
,
1854 int (*func
) (const char *filename
, void *data
),
1858 file_worker_func
**fpptr
= &func
;
1862 /* If a specific path was passed, search only the directories
1864 is_done
= foreach_dirinpath (search_path
, 0,
1865 foreachfile_callback
, fpptr
, data
);
1869 /* Otherwise search the default paths. */
1870 is_done
= foreach_dirinpath (user_search_path
, 0,
1871 foreachfile_callback
, fpptr
, data
);
1874 is_done
= foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR
), 0,
1875 foreachfile_callback
, fpptr
, data
);
1878 #if defined(LT_MODULE_PATH_VAR)
1881 is_done
= foreach_dirinpath (getenv(LT_MODULE_PATH_VAR
), 0,
1882 foreachfile_callback
, fpptr
, data
);
1885 #if defined(LT_DLSEARCH_PATH)
1886 if (!is_done
&& *sys_dlsearch_path
)
1888 is_done
= foreach_dirinpath (sys_dlsearch_path
, 0,
1889 foreachfile_callback
, fpptr
, data
);
1898 lt_dlclose (lt_dlhandle handle
)
1900 lt_dlhandle cur
, last
;
1903 /* check whether the handle is valid */
1904 last
= cur
= handles
;
1905 while (cur
&& handle
!= cur
)
1913 LT__SETERROR (INVALID_HANDLE
);
1919 cur
->info
.ref_count
--;
1921 /* Note that even with resident modules, we must track the ref_count
1922 correctly incase the user decides to reset the residency flag
1923 later (even though the API makes no provision for that at the
1925 if (cur
->info
.ref_count
<= 0 && !LT_DLIS_RESIDENT (cur
))
1927 lt_user_data data
= cur
->vtable
->dlloader_data
;
1931 last
->next
= cur
->next
;
1935 handles
= cur
->next
;
1938 errors
+= cur
->vtable
->module_close (data
, cur
->module
);
1939 errors
+= unload_deplibs (handle
);
1941 /* It is up to the callers to free the data itself. */
1942 FREE (cur
->interface_data
);
1944 FREE (cur
->info
.filename
);
1945 FREE (cur
->info
.name
);
1951 if (LT_DLIS_RESIDENT (handle
))
1953 LT__SETERROR (CLOSE_RESIDENT_MODULE
);
1962 lt_dlsym (lt_dlhandle place
, const char *symbol
)
1965 char lsym
[LT_SYMBOL_LENGTH
];
1973 LT__SETERROR (INVALID_HANDLE
);
1981 LT__SETERROR (SYMBOL_NOT_FOUND
);
1985 lensym
= LT_STRLEN (symbol
) + LT_STRLEN (handle
->vtable
->sym_prefix
)
1986 + LT_STRLEN (handle
->info
.name
);
1988 if (lensym
+ LT_SYMBOL_OVERHEAD
< LT_SYMBOL_LENGTH
)
1994 sym
= MALLOC (char, lensym
+ LT_SYMBOL_OVERHEAD
+ 1);
1997 LT__SETERROR (BUFFER_OVERFLOW
);
2002 data
= handle
->vtable
->dlloader_data
;
2003 if (handle
->info
.name
)
2005 const char *saved_error
;
2007 LT__GETERROR (saved_error
);
2009 /* this is a libtool module */
2010 if (handle
->vtable
->sym_prefix
)
2012 strcpy(sym
, handle
->vtable
->sym_prefix
);
2013 strcat(sym
, handle
->info
.name
);
2017 strcpy(sym
, handle
->info
.name
);
2020 strcat(sym
, "_LTX_");
2021 strcat(sym
, symbol
);
2023 /* try "modulename_LTX_symbol" */
2024 address
= handle
->vtable
->find_sym (data
, handle
->module
, sym
);
2033 LT__SETERRORSTR (saved_error
);
2036 /* otherwise try "symbol" */
2037 if (handle
->vtable
->sym_prefix
)
2039 strcpy(sym
, handle
->vtable
->sym_prefix
);
2040 strcat(sym
, symbol
);
2044 strcpy(sym
, symbol
);
2047 address
= handle
->vtable
->find_sym (data
, handle
->module
, sym
);
2061 LT__GETERROR (error
);
2062 LT__SETERRORSTR (0);
2064 return error
? error
: NULL
;
2068 lt_dlpath_insertdir (char **ppath
, char *before
, const char *dir
)
2071 char *canonical
= 0;
2073 size_t argz_len
= 0;
2076 assert (dir
&& *dir
);
2078 if (canonicalize_path (dir
, &canonical
) != 0)
2084 assert (canonical
&& *canonical
);
2086 /* If *PPATH is empty, set it to DIR. */
2089 assert (!before
); /* BEFORE cannot be set without PPATH. */
2090 assert (dir
); /* Without DIR, don't call this function! */
2092 *ppath
= lt__strdup (dir
);
2099 assert (ppath
&& *ppath
);
2101 if (argzize_path (*ppath
, &argz
, &argz_len
) != 0)
2107 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
2108 if *PPATH is already canonicalized, and hence does not change length
2109 with respect to ARGZ. We canonicalize each entry as it is added to
2110 the search path, and don't call this function with (uncanonicalized)
2111 user paths, so this is a fair assumption. */
2114 assert (*ppath
<= before
);
2115 assert ((int) (before
- *ppath
) <= (int) strlen (*ppath
));
2117 before
= before
- *ppath
+ argz
;
2120 if (lt_argz_insert (&argz
, &argz_len
, before
, dir
) != 0)
2126 argz_stringify (argz
, argz_len
, LT_PATHSEP_CHAR
);
2127 MEMREASSIGN(*ppath
, argz
);
2137 lt_dladdsearchdir (const char *search_dir
)
2141 if (search_dir
&& *search_dir
)
2143 if (lt_dlpath_insertdir (&user_search_path
, 0, search_dir
) != 0)
2151 lt_dlinsertsearchdir (const char *before
, const char *search_dir
)
2157 if ((before
< user_search_path
)
2158 || (before
>= user_search_path
+ LT_STRLEN (user_search_path
)))
2160 LT__SETERROR (INVALID_POSITION
);
2165 if (search_dir
&& *search_dir
)
2167 if (lt_dlpath_insertdir (&user_search_path
,
2168 (char *) before
, search_dir
) != 0)
2178 lt_dlsetsearchpath (const char *search_path
)
2182 FREE (user_search_path
);
2184 if (!search_path
|| !LT_STRLEN (search_path
))
2189 if (canonicalize_path (search_path
, &user_search_path
) != 0)
2196 lt_dlgetsearchpath (void)
2198 const char *saved_path
;
2200 saved_path
= user_search_path
;
2206 lt_dlmakeresident (lt_dlhandle handle
)
2212 LT__SETERROR (INVALID_HANDLE
);
2217 handle
->info
.is_resident
= 1;
2224 lt_dlisresident (lt_dlhandle handle
)
2228 LT__SETERROR (INVALID_HANDLE
);
2232 return LT_DLIS_RESIDENT (handle
);
2237 /* --- MODULE INFORMATION --- */
2240 const char *id_string
;
2241 lt_dlhandle_interface
*iface
;
2245 lt_dlinterface_register (const char *id_string
, lt_dlhandle_interface
*iface
)
2247 lt__interface_id
*interface_id
= (lt__interface_id
*) lt__malloc (sizeof *interface_id
);
2249 /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which
2250 can then be detected with lt_dlerror() if we return 0. */
2253 interface_id
->id_string
= lt__strdup (id_string
);
2254 if (!interface_id
->id_string
)
2255 FREE (interface_id
);
2257 interface_id
->iface
= iface
;
2260 return (lt_dlinterface_id
) interface_id
;
2263 void lt_dlinterface_free (lt_dlinterface_id key
)
2265 lt__interface_id
*interface_id
= (lt__interface_id
*)key
;
2266 FREE (interface_id
->id_string
);
2267 FREE (interface_id
);
2271 lt_dlcaller_set_data (lt_dlinterface_id key
, lt_dlhandle handle
, void *data
)
2274 void *stale
= (void *) 0;
2275 lt_dlhandle cur
= handle
;
2278 if (cur
->interface_data
)
2279 while (cur
->interface_data
[n_elements
].key
)
2282 for (i
= 0; i
< n_elements
; ++i
)
2284 if (cur
->interface_data
[i
].key
== key
)
2286 stale
= cur
->interface_data
[i
].data
;
2291 /* Ensure that there is enough room in this handle's interface_data
2292 array to accept a new element (and an empty end marker). */
2293 if (i
== n_elements
)
2295 lt_interface_data
*temp
2296 = REALLOC (lt_interface_data
, cur
->interface_data
, 2+ n_elements
);
2304 cur
->interface_data
= temp
;
2306 /* We only need this if we needed to allocate a new interface_data. */
2307 cur
->interface_data
[i
].key
= key
;
2308 cur
->interface_data
[1+ i
].key
= 0;
2311 cur
->interface_data
[i
].data
= data
;
2318 lt_dlcaller_get_data (lt_dlinterface_id key
, lt_dlhandle handle
)
2320 void *result
= (void *) 0;
2321 lt_dlhandle cur
= handle
;
2323 /* Locate the index of the element with a matching KEY. */
2324 if (cur
->interface_data
)
2327 for (i
= 0; cur
->interface_data
[i
].key
; ++i
)
2329 if (cur
->interface_data
[i
].key
== key
)
2331 result
= cur
->interface_data
[i
].data
;
2341 lt_dlgetinfo (lt_dlhandle handle
)
2345 LT__SETERROR (INVALID_HANDLE
);
2349 return &(handle
->info
);
2354 lt_dlhandle_iterate (lt_dlinterface_id iface
, lt_dlhandle place
)
2356 lt_dlhandle handle
= place
;
2357 lt__interface_id
*iterator
= (lt__interface_id
*) iface
;
2359 assert (iface
); /* iface is a required argument */
2364 handle
= handle
->next
;
2366 /* advance while the interface check fails */
2367 while (handle
&& iterator
->iface
2368 && ((*iterator
->iface
) (handle
, iterator
->id_string
) != 0))
2370 handle
= handle
->next
;
2378 lt_dlhandle_fetch (lt_dlinterface_id iface
, const char *module_name
)
2380 lt_dlhandle handle
= 0;
2382 assert (iface
); /* iface is a required argument */
2384 while ((handle
= lt_dlhandle_iterate (iface
, handle
)))
2386 lt_dlhandle cur
= handle
;
2387 if (cur
&& cur
->info
.name
&& streq (cur
->info
.name
, module_name
))
2396 lt_dlhandle_map (lt_dlinterface_id iface
,
2397 int (*func
) (lt_dlhandle handle
, void *data
), void *data
)
2399 lt__interface_id
*iterator
= (lt__interface_id
*) iface
;
2400 lt_dlhandle cur
= handles
;
2402 assert (iface
); /* iface is a required argument */
2408 /* advance while the interface check fails */
2409 while (cur
&& iterator
->iface
2410 && ((*iterator
->iface
) (cur
, iterator
->id_string
) != 0))
2415 if ((errorcode
= (*func
) (cur
, data
)) != 0)