* libltdl/m4/libtool.m4 (_LT_SYS_DYNAMIC_LINKER): Improve
[libtool.git] / libltdl / ltdl.c
blob1cf60857365ae5a1a7ced1a0d35652eba8228717
1 /* ltdl.c -- system independent dlopen wrapper
2 Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006 Free Software Foundation, Inc.
3 Originally by Thomas Tanner <tanner@ffii.org>
5 NOTE: The canonical source of this file is maintained with the
6 GNU Libtool package. Report bugs to bug-libtool@gnu.org.
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 As a special exception to the GNU Lesser General Public License,
14 if you distribute this file as part of a program or library that
15 is built using GNU libtool, you may include it under the same
16 distribution terms that you use for the rest of that program.
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301 USA
30 #include "lt_system.h"
31 #include "lt_dlloader.h"
32 #include "lt__private.h"
35 /* --- MANIFEST CONSTANTS --- */
38 /* Standard libltdl search path environment variable name */
39 #undef LTDL_SEARCHPATH_VAR
40 #define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
42 /* Standard libtool archive file extension. */
43 #undef LT_ARCHIVE_EXT
44 #define LT_ARCHIVE_EXT ".la"
46 /* max. filename length */
47 #if !defined(LT_FILENAME_MAX)
48 # define LT_FILENAME_MAX 1024
49 #endif
51 /* This is the maximum symbol size that won't require malloc/free */
52 #undef LT_SYMBOL_LENGTH
53 #define LT_SYMBOL_LENGTH 128
55 /* This accounts for the _LTX_ separator */
56 #undef LT_SYMBOL_OVERHEAD
57 #define LT_SYMBOL_OVERHEAD 5
60 /* Various boolean flags can be stored in the flags field of an
61 lt_dlhandle... */
62 #define LT_DLGET_FLAG(handle, flag) ((((lt__handle *) handle)->flags & (flag)) == (flag))
63 #define LT_DLSET_FLAG(handle, flag) (((lt__handle *)handle)->flags |= (flag))
65 #define LT_DLRESIDENT_FLAG (0x01 << 0)
66 /* ...add more flags here... */
68 #define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
71 static const char objdir[] = LT_OBJDIR;
72 static const char archive_ext[] = LT_ARCHIVE_EXT;
73 #if defined(LT_MODULE_EXT)
74 static const char shlib_ext[] = LT_MODULE_EXT;
75 #endif
76 #if defined(LT_DLSEARCH_PATH)
77 static const char sys_dlsearch_path[] = LT_DLSEARCH_PATH;
78 #endif
83 /* --- DYNAMIC MODULE LOADING --- */
86 /* The type of a function used at each iteration of foreach_dirinpath(). */
87 typedef int foreach_callback_func (char *filename, void *data1,
88 void *data2);
89 /* foreachfile_callback itself calls a function of this type: */
90 typedef int file_worker_func (const char *filename, void *data);
92 static int foreach_dirinpath (const char *search_path,
93 const char *base_name,
94 foreach_callback_func *func,
95 void *data1, void *data2);
97 static int find_file_callback (char *filename, void *data1,
98 void *data2);
99 static int find_handle_callback (char *filename, void *data,
100 void *ignored);
101 static int foreachfile_callback (char *filename, void *data1,
102 void *data2);
105 static int canonicalize_path (const char *path, char **pcanonical);
106 static int argzize_path (const char *path,
107 char **pargz, size_t *pargz_len);
108 static FILE *find_file (const char *search_path,
109 const char *base_name, char **pdir);
110 static lt_dlhandle *find_handle (const char *search_path,
111 const char *base_name,
112 lt_dlhandle *handle);
113 static int find_module (lt_dlhandle *handle, const char *dir,
114 const char *libdir, const char *dlname,
115 const char *old_name, int installed);
116 static int load_deplibs (lt_dlhandle handle, char *deplibs);
117 static int trim (char **dest, const char *str);
118 static int try_dlopen (lt_dlhandle *handle,
119 const char *filename);
120 static int tryall_dlopen (lt_dlhandle *handle,
121 const char *filename);
122 static int unload_deplibs (lt_dlhandle handle);
123 static int lt_argz_insert (char **pargz, size_t *pargz_len,
124 char *before, const char *entry);
125 static int lt_argz_insertinorder (char **pargz, size_t *pargz_len,
126 const char *entry);
127 static int lt_argz_insertdir (char **pargz, size_t *pargz_len,
128 const char *dirnam, struct dirent *dp);
129 static int lt_dlpath_insertdir (char **ppath, char *before,
130 const char *dir);
131 static int list_files_by_dir (const char *dirnam,
132 char **pargz, size_t *pargz_len);
133 static int file_not_found (void);
135 #ifdef HAVE_LIBDLLOADER
136 static int loader_init_callback (lt_dlhandle handle);
137 #endif /* HAVE_LIBDLLOADER */
139 static int loader_init (lt_get_vtable *vtable_func,
140 lt_user_data data);
142 static char *user_search_path= 0;
143 static lt_dlhandle handles = 0;
144 static int initialized = 0;
146 /* Our memory failure callback sets the error message to be passed back
147 up to the client, so we must be careful to return from mallocation
148 callers if allocation fails (as this callback returns!!). */
149 void
150 lt__alloc_die_callback (void)
152 LT__SETERROR (NO_MEMORY);
155 #ifdef HAVE_LIBDLLOADER
156 /* This function is called to initialise each preloaded module loader,
157 and hook it into the list of loaders to be used when attempting to
158 dlopen an application module. */
159 static int
160 loader_init_callback (lt_dlhandle handle)
162 lt_get_vtable *vtable_func = (lt_get_vtable *) lt_dlsym (handle, "get_vtable");
163 return loader_init (vtable_func, 0);
165 #endif /* HAVE_LIBDLLOADER */
167 static int
168 loader_init (lt_get_vtable *vtable_func, lt_user_data data)
170 const lt_dlvtable *vtable = 0;
171 int errors = 0;
173 if (vtable_func)
175 vtable = (*vtable_func) (data);
178 /* lt_dlloader_add will LT__SETERROR if it fails. */
179 errors += lt_dlloader_add (vtable);
181 assert (errors || vtable);
183 if ((!errors) && vtable->dlloader_init)
185 if ((*vtable->dlloader_init) (vtable->dlloader_data))
187 LT__SETERROR (INIT_LOADER);
188 ++errors;
192 return errors;
195 /* Bootstrap the loader loading with the preopening loader. */
196 #define get_vtable preopen_LTX_get_vtable
197 #define preloaded_symbols LT_CONC3(lt_, LTDLOPEN, _LTX_preloaded_symbols)
199 LT_BEGIN_C_DECLS
200 LT_SCOPE const lt_dlvtable * get_vtable (lt_user_data data);
201 LT_END_C_DECLS
202 #ifdef HAVE_LIBDLLOADER
203 extern lt_dlsymlist preloaded_symbols;
204 #endif
206 /* Initialize libltdl. */
208 lt_dlinit (void)
210 int errors = 0;
212 /* Initialize only at first call. */
213 if (++initialized == 1)
215 lt__alloc_die = lt__alloc_die_callback;
216 handles = 0;
217 user_search_path = 0; /* empty search path */
219 /* First set up the statically loaded preload module loader, so
220 we can use it to preopen the other loaders we linked in at
221 compile time. */
222 errors += loader_init (get_vtable, 0);
224 /* Now open all the preloaded module loaders, so the application
225 can use _them_ to lt_dlopen its own modules. */
226 #ifdef HAVE_LIBDLLOADER
227 if (!errors)
229 errors += lt_dlpreload (&preloaded_symbols);
232 if (!errors)
234 errors += lt_dlpreload_open (LT_STR(LTDLOPEN), loader_init_callback);
236 #endif /* HAVE_LIBDLLOADER */
239 return errors;
243 lt_dlexit (void)
245 /* shut down libltdl */
246 lt_dlloader *loader = 0;
247 lt__handle *handle = (lt__handle *) handles;
248 int errors = 0;
250 if (!initialized)
252 LT__SETERROR (SHUTDOWN);
253 ++errors;
254 goto done;
257 /* shut down only at last call. */
258 if (--initialized == 0)
260 int level;
262 while (handles && LT_DLIS_RESIDENT (handles))
264 handles = ((lt__handle *) handles)->next;
267 /* close all modules */
268 for (level = 1; handle; ++level)
270 lt__handle *cur = (lt__handle *) handles;
271 int saw_nonresident = 0;
273 while (cur)
275 lt__handle *tmp = cur;
276 cur = cur->next;
277 if (!LT_DLIS_RESIDENT (tmp))
279 saw_nonresident = 1;
280 if (tmp->info.ref_count <= level)
282 if (lt_dlclose (tmp))
284 ++errors;
289 /* done if only resident modules are left */
290 if (!saw_nonresident)
291 break;
294 /* close all loaders */
295 for (loader = (lt_dlloader *) lt_dlloader_next (NULL); loader;)
297 lt_dlloader *next = (lt_dlloader *) lt_dlloader_next (loader);
298 lt_dlvtable *vtable = (lt_dlvtable *) lt_dlloader_get (loader);
300 if ((vtable = lt_dlloader_remove ((char *) vtable->name)))
302 FREE (vtable);
304 else
306 ++errors;
309 loader = next;
312 FREE(user_search_path);
315 done:
316 return errors;
319 static int
320 tryall_dlopen (lt_dlhandle *phandle, const char *filename)
322 lt__handle * handle = (lt__handle *) handles;
323 const char * saved_error = 0;
324 int errors = 0;
326 LT__GETERROR (saved_error);
328 /* check whether the module was already opened */
329 for (;handle; handle = handle->next)
331 if ((handle->info.filename == filename) /* dlopen self: 0 == 0 */
332 || (handle->info.filename && filename
333 && streq (handle->info.filename, filename)))
335 break;
339 if (handle)
341 ++handle->info.ref_count;
342 *phandle = handle;
343 goto done;
346 handle = (lt__handle *) *phandle;
347 if (filename)
349 /* Comment out the check of file permissions using access.
350 This call seems to always return -1 with error EACCES.
352 /* We need to catch missing file errors early so that
353 file_not_found() can detect what happened.
354 if (access (filename, R_OK) != 0)
356 LT__SETERROR (FILE_NOT_FOUND);
357 ++errors;
358 goto done;
359 } */
361 handle->info.filename = lt__strdup (filename);
362 if (!handle->info.filename)
364 ++errors;
365 goto done;
368 else
370 handle->info.filename = 0;
374 const lt_dlvtable *vtable = 0;
375 lt_dlloader *loader = 0;
377 while ((loader = (lt_dlloader *) lt_dlloader_next (loader)))
379 vtable = lt_dlloader_get (loader);
380 handle->module = (*vtable->module_open) (vtable->dlloader_data,
381 filename);
383 if (handle->module != 0)
385 break;
389 if (!loader)
391 FREE (handle->info.filename);
392 ++errors;
393 goto done;
396 handle->vtable = vtable;
399 LT__SETERRORSTR (saved_error);
401 done:
402 return errors;
406 static int
407 tryall_dlopen_module (lt_dlhandle *handle, const char *prefix,
408 const char *dirname, const char *dlname)
410 int error = 0;
411 char *filename = 0;
412 size_t filename_len = 0;
413 size_t dirname_len = LT_STRLEN (dirname);
415 assert (handle);
416 assert (dirname);
417 assert (dlname);
418 #if defined(LT_DIRSEP_CHAR)
419 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
420 should make it into this function: */
421 assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
422 #endif
424 if (dirname_len > 0)
425 if (dirname[dirname_len -1] == '/')
426 --dirname_len;
427 filename_len = dirname_len + 1 + LT_STRLEN (dlname);
429 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
430 The PREFIX (if any) is handled below. */
431 filename = MALLOC (char, dirname_len + 1 + filename_len + 1);
432 if (!filename)
433 return 1;
435 sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
437 /* Now that we have combined DIRNAME and MODULENAME, if there is
438 also a PREFIX to contend with, simply recurse with the arguments
439 shuffled. Otherwise, attempt to open FILENAME as a module. */
440 if (prefix)
442 error += tryall_dlopen_module (handle,
443 (const char *) 0, prefix, filename);
445 else if (tryall_dlopen (handle, filename) != 0)
447 ++error;
450 FREE (filename);
451 return error;
454 static int
455 find_module (lt_dlhandle *handle, const char *dir, const char *libdir,
456 const char *dlname, const char *old_name, int installed)
458 /* Try to open the old library first; if it was dlpreopened,
459 we want the preopened version of it, even if a dlopenable
460 module is available. */
461 if (old_name && tryall_dlopen (handle, old_name) == 0)
463 return 0;
466 /* Try to open the dynamic library. */
467 if (dlname)
469 /* try to open the installed module */
470 if (installed && libdir)
472 if (tryall_dlopen_module (handle,
473 (const char *) 0, libdir, dlname) == 0)
474 return 0;
477 /* try to open the not-installed module */
478 if (!installed)
480 if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
481 return 0;
484 /* maybe it was moved to another directory */
486 if (dir && (tryall_dlopen_module (handle,
487 (const char *) 0, dir, dlname) == 0))
488 return 0;
492 return 1;
496 static int
497 canonicalize_path (const char *path, char **pcanonical)
499 char *canonical = 0;
501 assert (path && *path);
502 assert (pcanonical);
504 canonical = MALLOC (char, 1+ LT_STRLEN (path));
505 if (!canonical)
506 return 1;
509 size_t dest = 0;
510 size_t src;
511 for (src = 0; path[src] != LT_EOS_CHAR; ++src)
513 /* Path separators are not copied to the beginning or end of
514 the destination, or if another separator would follow
515 immediately. */
516 if (path[src] == LT_PATHSEP_CHAR)
518 if ((dest == 0)
519 || (path[1+ src] == LT_PATHSEP_CHAR)
520 || (path[1+ src] == LT_EOS_CHAR))
521 continue;
524 /* Anything other than a directory separator is copied verbatim. */
525 if ((path[src] != '/')
526 #if defined(LT_DIRSEP_CHAR)
527 && (path[src] != LT_DIRSEP_CHAR)
528 #endif
531 canonical[dest++] = path[src];
533 /* Directory separators are converted and copied only if they are
534 not at the end of a path -- i.e. before a path separator or
535 NULL terminator. */
536 else if ((path[1+ src] != LT_PATHSEP_CHAR)
537 && (path[1+ src] != LT_EOS_CHAR)
538 #if defined(LT_DIRSEP_CHAR)
539 && (path[1+ src] != LT_DIRSEP_CHAR)
540 #endif
541 && (path[1+ src] != '/'))
543 canonical[dest++] = '/';
547 /* Add an end-of-string marker at the end. */
548 canonical[dest] = LT_EOS_CHAR;
551 /* Assign new value. */
552 *pcanonical = canonical;
554 return 0;
557 static int
558 argzize_path (const char *path, char **pargz, size_t *pargz_len)
560 error_t error;
562 assert (path);
563 assert (pargz);
564 assert (pargz_len);
566 if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
568 switch (error)
570 case ENOMEM:
571 LT__SETERROR (NO_MEMORY);
572 break;
573 default:
574 LT__SETERROR (UNKNOWN);
575 break;
578 return 1;
581 return 0;
584 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
585 of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
586 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
587 it is appended to each SEARCH_PATH element before FUNC is called. */
588 static int
589 foreach_dirinpath (const char *search_path, const char *base_name,
590 foreach_callback_func *func, void *data1, void *data2)
592 int result = 0;
593 size_t filenamesize = 0;
594 size_t lenbase = LT_STRLEN (base_name);
595 size_t argz_len = 0;
596 char *argz = 0;
597 char *filename = 0;
598 char *canonical = 0;
600 if (!search_path || !*search_path)
602 LT__SETERROR (FILE_NOT_FOUND);
603 goto cleanup;
606 if (canonicalize_path (search_path, &canonical) != 0)
607 goto cleanup;
609 if (argzize_path (canonical, &argz, &argz_len) != 0)
610 goto cleanup;
613 char *dir_name = 0;
614 while ((dir_name = argz_next (argz, argz_len, dir_name)))
616 size_t lendir = LT_STRLEN (dir_name);
618 if (1+ lendir + lenbase >= filenamesize)
620 FREE (filename);
621 filenamesize = 1+ lendir + 1+ lenbase; /* "/d" + '/' + "f" + '\0' */
622 filename = MALLOC (char, filenamesize);
623 if (!filename)
624 goto cleanup;
627 assert (filenamesize > lendir);
628 strcpy (filename, dir_name);
630 if (base_name && *base_name)
632 if (filename[lendir -1] != '/')
633 filename[lendir++] = '/';
634 strcpy (filename +lendir, base_name);
637 if ((result = (*func) (filename, data1, data2)))
639 break;
644 cleanup:
645 FREE (argz);
646 FREE (canonical);
647 FREE (filename);
649 return result;
652 /* If FILEPATH can be opened, store the name of the directory component
653 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
654 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
655 static int
656 find_file_callback (char *filename, void *data1, void *data2)
658 char **pdir = (char **) data1;
659 FILE **pfile = (FILE **) data2;
660 int is_done = 0;
662 assert (filename && *filename);
663 assert (pdir);
664 assert (pfile);
666 if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
668 char *dirend = strrchr (filename, '/');
670 if (dirend > filename)
671 *dirend = LT_EOS_CHAR;
673 FREE (*pdir);
674 *pdir = lt__strdup (filename);
675 is_done = (*pdir == 0) ? -1 : 1;
678 return is_done;
681 static FILE *
682 find_file (const char *search_path, const char *base_name, char **pdir)
684 FILE *file = 0;
686 foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
688 return file;
691 static int
692 find_handle_callback (char *filename, void *data, void * LT__UNUSED ignored)
694 lt_dlhandle *handle = (lt_dlhandle *) data;
695 int notfound = access (filename, R_OK);
697 /* Bail out if file cannot be read... */
698 if (notfound)
699 return 0;
701 /* Try to dlopen the file, but do not continue searching in any
702 case. */
703 if (tryall_dlopen (handle, filename) != 0)
704 *handle = 0;
706 return 1;
709 /* If HANDLE was found return it, otherwise return 0. If HANDLE was
710 found but could not be opened, *HANDLE will be set to 0. */
711 static lt_dlhandle *
712 find_handle (const char *search_path, const char *base_name,
713 lt_dlhandle *handle)
715 if (!search_path)
716 return 0;
718 if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
719 handle, 0))
720 return 0;
722 return handle;
725 #if !defined(LTDL_DLOPEN_DEPLIBS)
726 static int
727 load_deplibs (lt_dlhandle handle, char * LT__UNUSED deplibs)
729 ((lt__handle *) handle)->depcount = 0;
730 return 0;
733 #else /* defined(LTDL_DLOPEN_DEPLIBS) */
734 static int
735 load_deplibs (lt_dlhandle handle, char *deplibs)
737 char *p, *save_search_path = 0;
738 int depcount = 0;
739 int i;
740 char **names = 0;
741 int errors = 0;
743 ((lt__handle *) handle)->depcount = 0;
745 if (!deplibs)
747 return errors;
749 ++errors;
751 if (user_search_path)
753 save_search_path = lt__strdup (user_search_path);
754 if (!save_search_path)
755 goto cleanup;
758 /* extract search paths and count deplibs */
759 p = deplibs;
760 while (*p)
762 if (!isspace ((unsigned char) *p))
764 char *end = p+1;
765 while (*end && !isspace((unsigned char) *end))
767 ++end;
770 if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
772 char save = *end;
773 *end = 0; /* set a temporary string terminator */
774 if (lt_dladdsearchdir(p+2))
776 goto cleanup;
778 *end = save;
780 else
782 ++depcount;
785 p = end;
787 else
789 ++p;
794 if (!depcount)
796 errors = 0;
797 goto cleanup;
800 names = MALLOC (char *, depcount);
801 if (!names)
802 goto cleanup;
804 /* now only extract the actual deplibs */
805 depcount = 0;
806 p = deplibs;
807 while (*p)
809 if (isspace ((unsigned char) *p))
811 ++p;
813 else
815 char *end = p+1;
816 while (*end && !isspace ((unsigned char) *end))
818 ++end;
821 if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
823 char *name;
824 char save = *end;
825 *end = 0; /* set a temporary string terminator */
826 if (strncmp(p, "-l", 2) == 0)
828 size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
829 name = MALLOC (char, 1+ name_len);
830 if (name)
831 sprintf (name, "lib%s", p+2);
833 else
834 name = lt__strdup(p);
836 if (!name)
837 goto cleanup_names;
839 names[depcount++] = name;
840 *end = save;
842 p = end;
846 /* load the deplibs (in reverse order)
847 At this stage, don't worry if the deplibs do not load correctly,
848 they may already be statically linked into the loading application
849 for instance. There will be a more enlightening error message
850 later on if the loaded module cannot resolve all of its symbols. */
851 if (depcount)
853 lt__handle *cur = (lt__handle *) handle;
854 int j = 0;
856 cur->deplibs = (lt_dlhandle *) MALLOC (lt__handle, depcount);
857 if (!cur->deplibs)
858 goto cleanup_names;
860 for (i = 0; i < depcount; ++i)
862 cur->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
863 if (cur->deplibs[j])
865 ++j;
869 cur->depcount = j; /* Number of successfully loaded deplibs */
870 errors = 0;
873 cleanup_names:
874 for (i = 0; i < depcount; ++i)
876 FREE (names[i]);
879 cleanup:
880 FREE (names);
881 /* restore the old search path */
882 if (save_search_path) {
883 MEMREASSIGN (user_search_path, save_search_path);
886 return errors;
888 #endif /* defined(LTDL_DLOPEN_DEPLIBS) */
890 static int
891 unload_deplibs (lt_dlhandle handle)
893 int i;
894 int errors = 0;
895 lt__handle *cur = (lt__handle *) handle;
897 if (cur->depcount)
899 for (i = 0; i < cur->depcount; ++i)
901 if (!LT_DLIS_RESIDENT (cur->deplibs[i]))
903 errors += lt_dlclose (cur->deplibs[i]);
906 FREE (cur->deplibs);
909 return errors;
912 static int
913 trim (char **dest, const char *str)
915 /* remove the leading and trailing "'" from str
916 and store the result in dest */
917 const char *end = strrchr (str, '\'');
918 size_t len = LT_STRLEN (str);
919 char *tmp;
921 FREE (*dest);
923 if (!end)
924 return 1;
926 if (len > 3 && str[0] == '\'')
928 tmp = MALLOC (char, end - str);
929 if (!tmp)
930 return 1;
932 memcpy(tmp, &str[1], (end - str) - 1);
933 tmp[len-3] = LT_EOS_CHAR;
934 *dest = tmp;
936 else
938 *dest = 0;
941 return 0;
944 /* Read the .la file FILE. */
945 static int
946 parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs,
947 char **old_name, int *installed)
949 int errors = 0;
950 size_t line_len = LT_FILENAME_MAX;
951 char * line = MALLOC (char, line_len);
953 if (!line)
955 LT__SETERROR (FILE_NOT_FOUND);
956 return 1;
959 while (!feof (file))
961 if (!fgets (line, (int) line_len, file))
963 break;
966 /* Handle the case where we occasionally need to read a line
967 that is longer than the initial buffer size. */
968 while ((line[LT_STRLEN(line) -1] != '\n') && (!feof (file)))
970 line = REALLOC (char, line, line_len *2);
971 if (!line)
973 fclose (file);
974 ++errors;
975 goto cleanup;
977 if (!fgets (&line[line_len -1], (int) line_len +1, file))
979 break;
981 line_len *= 2;
984 if (line[0] == '\n' || line[0] == '#')
986 continue;
989 #undef STR_DLNAME
990 #define STR_DLNAME "dlname="
991 if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
993 errors += trim (dlname, &line[sizeof (STR_DLNAME) - 1]);
996 #undef STR_OLD_LIBRARY
997 #define STR_OLD_LIBRARY "old_library="
998 else if (strncmp (line, STR_OLD_LIBRARY,
999 sizeof (STR_OLD_LIBRARY) - 1) == 0)
1001 errors += trim (old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
1003 #undef STR_LIBDIR
1004 #define STR_LIBDIR "libdir="
1005 else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
1007 errors += trim (libdir, &line[sizeof(STR_LIBDIR) - 1]);
1010 #undef STR_DL_DEPLIBS
1011 #define STR_DL_DEPLIBS "dependency_libs="
1012 else if (strncmp (line, STR_DL_DEPLIBS,
1013 sizeof (STR_DL_DEPLIBS) - 1) == 0)
1015 errors += trim (deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
1017 else if (streq (line, "installed=yes\n"))
1019 *installed = 1;
1021 else if (streq (line, "installed=no\n"))
1023 *installed = 0;
1026 #undef STR_LIBRARY_NAMES
1027 #define STR_LIBRARY_NAMES "library_names="
1028 else if (!*dlname && strncmp (line, STR_LIBRARY_NAMES,
1029 sizeof (STR_LIBRARY_NAMES) - 1) == 0)
1031 char *last_libname;
1032 errors += trim (dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
1033 if (!errors
1034 && *dlname
1035 && (last_libname = strrchr (*dlname, ' ')) != 0)
1037 last_libname = lt__strdup (last_libname + 1);
1038 if (!last_libname)
1040 ++errors;
1041 goto cleanup;
1043 MEMREASSIGN (*dlname, last_libname);
1047 if (errors)
1048 break;
1050 cleanup:
1051 FREE (line);
1052 return errors;
1055 /* Try to open FILENAME as a module. */
1056 static int
1057 try_dlopen (lt_dlhandle *phandle, const char *filename)
1059 const char * ext = 0;
1060 const char * saved_error = 0;
1061 char * canonical = 0;
1062 char * base_name = 0;
1063 char * dir = 0;
1064 char * name = 0;
1065 int errors = 0;
1066 lt_dlhandle newhandle;
1068 assert (phandle);
1069 assert (*phandle == 0);
1071 LT__GETERROR (saved_error);
1073 /* dlopen self? */
1074 if (!filename)
1076 *phandle = (lt_dlhandle) lt__zalloc (sizeof (lt__handle));
1077 if (*phandle == 0)
1078 return 1;
1080 newhandle = *phandle;
1082 /* lt_dlclose()ing yourself is very bad! Disallow it. */
1083 LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
1085 if (tryall_dlopen (&newhandle, 0) != 0)
1087 FREE (*phandle);
1088 return 1;
1091 goto register_handle;
1094 assert (filename && *filename);
1096 /* Doing this immediately allows internal functions to safely
1097 assume only canonicalized paths are passed. */
1098 if (canonicalize_path (filename, &canonical) != 0)
1100 ++errors;
1101 goto cleanup;
1104 /* If the canonical module name is a path (relative or absolute)
1105 then split it into a directory part and a name part. */
1106 base_name = strrchr (canonical, '/');
1107 if (base_name)
1109 size_t dirlen = (1+ base_name) - canonical;
1111 dir = MALLOC (char, 1+ dirlen);
1112 if (!dir)
1114 ++errors;
1115 goto cleanup;
1118 strncpy (dir, canonical, dirlen);
1119 dir[dirlen] = LT_EOS_CHAR;
1121 ++base_name;
1123 else
1124 MEMREASSIGN (base_name, canonical);
1126 assert (base_name && *base_name);
1128 ext = strrchr (base_name, '.');
1129 if (!ext)
1131 ext = base_name + LT_STRLEN (base_name);
1134 /* extract the module name from the file name */
1135 name = MALLOC (char, ext - base_name + 1);
1136 if (!name)
1138 ++errors;
1139 goto cleanup;
1142 /* canonicalize the module name */
1144 int i;
1145 for (i = 0; i < ext - base_name; ++i)
1147 if (isalnum ((unsigned char)(base_name[i])))
1149 name[i] = base_name[i];
1151 else
1153 name[i] = '_';
1156 name[ext - base_name] = LT_EOS_CHAR;
1159 /* Check whether we are opening a libtool module (.la extension). */
1160 if (ext && streq (ext, archive_ext))
1162 /* this seems to be a libtool module */
1163 FILE * file = 0;
1164 char * dlname = 0;
1165 char * old_name = 0;
1166 char * libdir = 0;
1167 char * deplibs = 0;
1169 /* if we can't find the installed flag, it is probably an
1170 installed libtool archive, produced with an old version
1171 of libtool */
1172 int installed = 1;
1175 /* Now try to open the .la file. If there is no directory name
1176 component, try to find it first in user_search_path and then other
1177 prescribed paths. Otherwise (or in any case if the module was not
1178 yet found) try opening just the module name as passed. */
1179 if (!dir)
1181 const char *search_path;
1183 search_path = user_search_path;
1184 if (search_path)
1185 file = find_file (user_search_path, base_name, &dir);
1187 if (!file)
1189 search_path = getenv (LTDL_SEARCHPATH_VAR);
1190 if (search_path)
1191 file = find_file (search_path, base_name, &dir);
1194 #if defined(LT_MODULE_PATH_VAR)
1195 if (!file)
1197 search_path = getenv (LT_MODULE_PATH_VAR);
1198 if (search_path)
1199 file = find_file (search_path, base_name, &dir);
1201 #endif
1202 #if defined(LT_DLSEARCH_PATH)
1203 if (!file && sys_dlsearch_path)
1205 file = find_file (sys_dlsearch_path, base_name, &dir);
1207 #endif
1209 if (!file)
1211 file = fopen (filename, LT_READTEXT_MODE);
1214 /* If we didn't find the file by now, it really isn't there. Set
1215 the status flag, and bail out. */
1216 if (!file)
1218 LT__SETERROR (FILE_NOT_FOUND);
1219 ++errors;
1220 goto cleanup;
1223 /* read the .la file */
1224 if (parse_dotla_file(file, &dlname, &libdir, &deplibs,
1225 &old_name, &installed) != 0)
1226 errors++;
1228 fclose (file);
1230 /* allocate the handle */
1231 *phandle = (lt_dlhandle) lt__zalloc (sizeof (lt__handle));
1232 if (*phandle == 0)
1233 ++errors;
1235 if (errors)
1237 FREE (dlname);
1238 FREE (old_name);
1239 FREE (libdir);
1240 FREE (deplibs);
1241 FREE (*phandle);
1242 goto cleanup;
1245 assert (*phandle);
1247 if (load_deplibs (*phandle, deplibs) == 0)
1249 newhandle = *phandle;
1250 /* find_module may replace newhandle */
1251 if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
1253 unload_deplibs (*phandle);
1254 ++errors;
1257 else
1259 ++errors;
1262 FREE (dlname);
1263 FREE (old_name);
1264 FREE (libdir);
1265 FREE (deplibs);
1267 if (errors)
1269 FREE (*phandle);
1270 goto cleanup;
1273 if (*phandle != newhandle)
1275 unload_deplibs (*phandle);
1278 else
1280 /* not a libtool module */
1281 *phandle = (lt_dlhandle) lt__zalloc (sizeof (lt__handle));
1282 if (*phandle == 0)
1284 ++errors;
1285 goto cleanup;
1288 newhandle = *phandle;
1290 /* If the module has no directory name component, try to find it
1291 first in user_search_path and then other prescribed paths.
1292 Otherwise (or in any case if the module was not yet found) try
1293 opening just the module name as passed. */
1294 if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
1295 && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
1296 &newhandle)
1297 #if defined(LT_MODULE_PATH_VAR)
1298 && !find_handle (getenv (LT_MODULE_PATH_VAR), base_name,
1299 &newhandle)
1300 #endif
1301 #if defined(LT_DLSEARCH_PATH)
1302 && !find_handle (sys_dlsearch_path, base_name, &newhandle)
1303 #endif
1306 if (tryall_dlopen (&newhandle, filename) != 0)
1308 newhandle = NULL;
1312 if (!newhandle)
1314 FREE (*phandle);
1315 ++errors;
1316 goto cleanup;
1320 register_handle:
1321 MEMREASSIGN (*phandle, newhandle);
1323 if (((lt__handle *) *phandle)->info.ref_count == 0)
1325 ((lt__handle *) *phandle)->info.ref_count = 1;
1326 MEMREASSIGN (((lt__handle *) *phandle)->info.name, name);
1328 ((lt__handle *) *phandle)->next = (lt__handle *) handles;
1329 handles = *phandle;
1332 LT__SETERRORSTR (saved_error);
1334 cleanup:
1335 FREE (dir);
1336 FREE (name);
1337 if (!canonical) /* was MEMREASSIGNed */
1338 FREE (base_name);
1339 FREE (canonical);
1341 return errors;
1344 lt_dlhandle
1345 lt_dlopen (const char *filename)
1347 lt_dlhandle handle = 0;
1349 /* Just incase we missed a code path in try_dlopen() that reports
1350 an error, but forgets to reset handle... */
1351 if (try_dlopen (&handle, filename) != 0)
1352 return 0;
1354 return handle;
1357 /* If the last error messge store was `FILE_NOT_FOUND', then return
1358 non-zero. */
1359 static int
1360 file_not_found (void)
1362 const char *error = 0;
1364 LT__GETERROR (error);
1365 if (error == LT__STRERROR (FILE_NOT_FOUND))
1366 return 1;
1368 return 0;
1371 /* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to
1372 open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
1373 and if a file is still not found try again with MODULE_EXT appended
1374 instead. */
1375 lt_dlhandle
1376 lt_dlopenext (const char *filename)
1378 lt_dlhandle handle = 0;
1379 char * tmp = 0;
1380 char * ext = 0;
1381 size_t len;
1382 int errors = 0;
1384 if (!filename)
1386 return lt_dlopen (filename);
1389 assert (filename);
1391 len = LT_STRLEN (filename);
1392 ext = strrchr (filename, '.');
1394 /* If FILENAME already bears a suitable extension, there is no need
1395 to try appending additional extensions. */
1396 if (ext && ((streq (ext, archive_ext))
1397 #if defined(LT_MODULE_EXT)
1398 || (streq (ext, shlib_ext))
1399 #endif
1402 return lt_dlopen (filename);
1405 /* First try appending ARCHIVE_EXT. */
1406 tmp = MALLOC (char, len + LT_STRLEN (archive_ext) + 1);
1407 if (!tmp)
1408 return 0;
1410 strcpy (tmp, filename);
1411 strcat (tmp, archive_ext);
1412 errors = try_dlopen (&handle, tmp);
1414 /* If we found FILENAME, stop searching -- whether we were able to
1415 load the file as a module or not. If the file exists but loading
1416 failed, it is better to return an error message here than to
1417 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
1418 in the module search path. */
1419 if (handle || ((errors > 0) && !file_not_found ()))
1421 FREE (tmp);
1422 return handle;
1425 #if defined(LT_MODULE_EXT)
1426 /* Try appending MODULE_EXT. */
1427 if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
1429 FREE (tmp);
1430 tmp = MALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
1431 if (!tmp)
1432 return 0;
1434 strcpy (tmp, filename);
1436 else
1438 tmp[len] = LT_EOS_CHAR;
1441 strcat(tmp, shlib_ext);
1442 errors = try_dlopen (&handle, tmp);
1444 /* As before, if the file was found but loading failed, return now
1445 with the current error message. */
1446 if (handle || ((errors > 0) && !file_not_found ()))
1448 FREE (tmp);
1449 return handle;
1451 #endif
1453 /* Still here? Then we really did fail to locate any of the file
1454 names we tried. */
1455 LT__SETERROR (FILE_NOT_FOUND);
1456 FREE (tmp);
1457 return 0;
1461 static int
1462 lt_argz_insert (char **pargz, size_t *pargz_len, char *before,
1463 const char *entry)
1465 error_t error;
1467 /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
1468 pargz_len, NULL, entry) failed with EINVAL. */
1469 if (before)
1470 error = argz_insert (pargz, pargz_len, before, entry);
1471 else
1472 error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry));
1474 if (error)
1476 switch (error)
1478 case ENOMEM:
1479 LT__SETERROR (NO_MEMORY);
1480 break;
1481 default:
1482 LT__SETERROR (UNKNOWN);
1483 break;
1485 return 1;
1488 return 0;
1491 static int
1492 lt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry)
1494 char *before = 0;
1496 assert (pargz);
1497 assert (pargz_len);
1498 assert (entry && *entry);
1500 if (*pargz)
1501 while ((before = argz_next (*pargz, *pargz_len, before)))
1503 int cmp = strcmp (entry, before);
1505 if (cmp < 0) break;
1506 if (cmp == 0) return 0; /* No duplicates! */
1509 return lt_argz_insert (pargz, pargz_len, before, entry);
1512 static int
1513 lt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam,
1514 struct dirent *dp)
1516 char *buf = 0;
1517 size_t buf_len = 0;
1518 char *end = 0;
1519 size_t end_offset = 0;
1520 size_t dir_len = 0;
1521 int errors = 0;
1523 assert (pargz);
1524 assert (pargz_len);
1525 assert (dp);
1527 dir_len = LT_STRLEN (dirnam);
1528 end = dp->d_name + D_NAMLEN(dp);
1530 /* Ignore version numbers. */
1532 char *p;
1533 for (p = end; p -1 > dp->d_name; --p)
1534 if (strchr (".0123456789", p[-1]) == 0)
1535 break;
1537 if (*p == '.')
1538 end = p;
1541 /* Ignore filename extension. */
1543 char *p;
1544 for (p = end -1; p > dp->d_name; --p)
1545 if (*p == '.')
1547 end = p;
1548 break;
1552 /* Prepend the directory name. */
1553 end_offset = end - dp->d_name;
1554 buf_len = dir_len + 1+ end_offset;
1555 buf = MALLOC (char, 1+ buf_len);
1556 if (!buf)
1557 return ++errors;
1559 assert (buf);
1561 strcpy (buf, dirnam);
1562 strcat (buf, "/");
1563 strncat (buf, dp->d_name, end_offset);
1564 buf[buf_len] = LT_EOS_CHAR;
1566 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
1567 if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
1568 ++errors;
1570 FREE (buf);
1572 return errors;
1575 static int
1576 list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len)
1578 DIR *dirp = 0;
1579 int errors = 0;
1581 assert (dirnam && *dirnam);
1582 assert (pargz);
1583 assert (pargz_len);
1584 assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
1586 dirp = opendir (dirnam);
1587 if (dirp)
1589 struct dirent *dp = 0;
1591 while ((dp = readdir (dirp)))
1592 if (dp->d_name[0] != '.')
1593 if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
1595 ++errors;
1596 break;
1599 closedir (dirp);
1601 else
1602 ++errors;
1604 return errors;
1608 /* If there are any files in DIRNAME, call the function passed in
1609 DATA1 (with the name of each file and DATA2 as arguments). */
1610 static int
1611 foreachfile_callback (char *dirname, void *data1, void *data2)
1613 file_worker_func *func = *(file_worker_func **) data1;
1615 int is_done = 0;
1616 char *argz = 0;
1617 size_t argz_len = 0;
1619 if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
1620 goto cleanup;
1621 if (!argz)
1622 goto cleanup;
1625 char *filename = 0;
1626 while ((filename = argz_next (argz, argz_len, filename)))
1627 if ((is_done = (*func) (filename, data2)))
1628 break;
1631 cleanup:
1632 FREE (argz);
1634 return is_done;
1638 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
1639 with DATA. The filenames passed to FUNC would be suitable for
1640 passing to lt_dlopenext. The extensions are stripped so that
1641 individual modules do not generate several entries (e.g. libfoo.la,
1642 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
1643 then the same directories that lt_dlopen would search are examined. */
1645 lt_dlforeachfile (const char *search_path,
1646 int (*func) (const char *filename, void *data),
1647 void *data)
1649 int is_done = 0;
1650 file_worker_func **fpptr = &func;
1652 if (search_path)
1654 /* If a specific path was passed, search only the directories
1655 listed in it. */
1656 is_done = foreach_dirinpath (search_path, 0,
1657 foreachfile_callback, fpptr, data);
1659 else
1661 /* Otherwise search the default paths. */
1662 is_done = foreach_dirinpath (user_search_path, 0,
1663 foreachfile_callback, fpptr, data);
1664 if (!is_done)
1666 is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0,
1667 foreachfile_callback, fpptr, data);
1670 #if defined(LT_MODULE_PATH_VAR)
1671 if (!is_done)
1673 is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0,
1674 foreachfile_callback, fpptr, data);
1676 #endif
1677 #if defined(LT_DLSEARCH_PATH)
1678 if (!is_done && sys_dlsearch_path)
1680 is_done = foreach_dirinpath (sys_dlsearch_path, 0,
1681 foreachfile_callback, fpptr, data);
1683 #endif
1686 return is_done;
1690 lt_dlclose (lt_dlhandle handle)
1692 lt__handle *cur, *last;
1693 int errors = 0;
1695 /* check whether the handle is valid */
1696 last = cur = (lt__handle *) handles;
1697 while (cur && handle != cur)
1699 last = cur;
1700 cur = cur->next;
1703 if (!cur)
1705 LT__SETERROR (INVALID_HANDLE);
1706 ++errors;
1707 goto done;
1710 cur = (lt__handle *) handle;
1711 cur->info.ref_count--;
1713 /* Note that even with resident modules, we must track the ref_count
1714 correctly incase the user decides to reset the residency flag
1715 later (even though the API makes no provision for that at the
1716 moment). */
1717 if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur))
1719 lt_user_data data = cur->vtable->dlloader_data;
1721 if (cur != handles)
1723 last->next = cur->next;
1725 else
1727 handles = cur->next;
1730 errors += cur->vtable->module_close (data, cur->module);
1731 errors += unload_deplibs (handle);
1733 /* It is up to the callers to free the data itself. */
1734 FREE (cur->interface_data);
1736 FREE (cur->info.filename);
1737 FREE (cur->info.name);
1738 FREE (cur);
1740 goto done;
1743 if (LT_DLIS_RESIDENT (handle))
1745 LT__SETERROR (CLOSE_RESIDENT_MODULE);
1746 ++errors;
1749 done:
1750 return errors;
1753 void *
1754 lt_dlsym (lt_dlhandle place, const char *symbol)
1756 size_t lensym;
1757 char lsym[LT_SYMBOL_LENGTH];
1758 char *sym;
1759 void *address;
1760 lt_user_data data;
1761 lt__handle *handle;
1763 if (!place)
1765 LT__SETERROR (INVALID_HANDLE);
1766 return 0;
1769 handle = (lt__handle *) place;
1771 if (!symbol)
1773 LT__SETERROR (SYMBOL_NOT_FOUND);
1774 return 0;
1777 lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->vtable->sym_prefix)
1778 + LT_STRLEN (handle->info.name);
1780 if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
1782 sym = lsym;
1784 else
1786 sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
1787 if (!sym)
1789 LT__SETERROR (BUFFER_OVERFLOW);
1790 return 0;
1794 data = handle->vtable->dlloader_data;
1795 if (handle->info.name)
1797 const char *saved_error;
1799 LT__GETERROR (saved_error);
1801 /* this is a libtool module */
1802 if (handle->vtable->sym_prefix)
1804 strcpy(sym, handle->vtable->sym_prefix);
1805 strcat(sym, handle->info.name);
1807 else
1809 strcpy(sym, handle->info.name);
1812 strcat(sym, "_LTX_");
1813 strcat(sym, symbol);
1815 /* try "modulename_LTX_symbol" */
1816 address = handle->vtable->find_sym (data, handle->module, sym);
1817 if (address)
1819 if (sym != lsym)
1821 FREE (sym);
1823 return address;
1825 LT__SETERRORSTR (saved_error);
1828 /* otherwise try "symbol" */
1829 if (handle->vtable->sym_prefix)
1831 strcpy(sym, handle->vtable->sym_prefix);
1832 strcat(sym, symbol);
1834 else
1836 strcpy(sym, symbol);
1839 address = handle->vtable->find_sym (data, handle->module, sym);
1840 if (sym != lsym)
1842 FREE (sym);
1845 return address;
1848 const char *
1849 lt_dlerror (void)
1851 const char *error;
1853 LT__GETERROR (error);
1854 LT__SETERRORSTR (0);
1856 return error ? error : NULL;
1859 static int
1860 lt_dlpath_insertdir (char **ppath, char *before, const char *dir)
1862 int errors = 0;
1863 char *canonical = 0;
1864 char *argz = 0;
1865 size_t argz_len = 0;
1867 assert (ppath);
1868 assert (dir && *dir);
1870 if (canonicalize_path (dir, &canonical) != 0)
1872 ++errors;
1873 goto cleanup;
1876 assert (canonical && *canonical);
1878 /* If *PPATH is empty, set it to DIR. */
1879 if (*ppath == 0)
1881 assert (!before); /* BEFORE cannot be set without PPATH. */
1882 assert (dir); /* Without DIR, don't call this function! */
1884 *ppath = lt__strdup (dir);
1885 if (*ppath == 0)
1886 ++errors;
1888 goto cleanup;
1891 assert (ppath && *ppath);
1893 if (argzize_path (*ppath, &argz, &argz_len) != 0)
1895 ++errors;
1896 goto cleanup;
1899 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
1900 if *PPATH is already canonicalized, and hence does not change length
1901 with respect to ARGZ. We canonicalize each entry as it is added to
1902 the search path, and don't call this function with (uncanonicalized)
1903 user paths, so this is a fair assumption. */
1904 if (before)
1906 assert (*ppath <= before);
1907 assert ((int) (before - *ppath) <= (int) strlen (*ppath));
1909 before = before - *ppath + argz;
1912 if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
1914 ++errors;
1915 goto cleanup;
1918 argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
1919 MEMREASSIGN(*ppath, argz);
1921 cleanup:
1922 FREE (argz);
1923 FREE (canonical);
1925 return errors;
1929 lt_dladdsearchdir (const char *search_dir)
1931 int errors = 0;
1933 if (search_dir && *search_dir)
1935 if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
1936 ++errors;
1939 return errors;
1943 lt_dlinsertsearchdir (const char *before, const char *search_dir)
1945 int errors = 0;
1947 if (before)
1949 if ((before < user_search_path)
1950 || (before >= user_search_path + LT_STRLEN (user_search_path)))
1952 LT__SETERROR (INVALID_POSITION);
1953 return 1;
1957 if (search_dir && *search_dir)
1959 if (lt_dlpath_insertdir (&user_search_path,
1960 (char *) before, search_dir) != 0)
1962 ++errors;
1966 return errors;
1970 lt_dlsetsearchpath (const char *search_path)
1972 int errors = 0;
1974 FREE (user_search_path);
1976 if (!search_path || !LT_STRLEN (search_path))
1978 return errors;
1981 if (canonicalize_path (search_path, &user_search_path) != 0)
1982 ++errors;
1984 return errors;
1987 const char *
1988 lt_dlgetsearchpath (void)
1990 const char *saved_path;
1992 saved_path = user_search_path;
1994 return saved_path;
1998 lt_dlmakeresident (lt_dlhandle handle)
2000 int errors = 0;
2002 if (!handle)
2004 LT__SETERROR (INVALID_HANDLE);
2005 ++errors;
2007 else
2009 LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
2012 return errors;
2016 lt_dlisresident (lt_dlhandle handle)
2018 if (!handle)
2020 LT__SETERROR (INVALID_HANDLE);
2021 return -1;
2024 return LT_DLIS_RESIDENT (handle);
2030 /* --- MODULE INFORMATION --- */
2032 typedef struct {
2033 const char *id_string;
2034 lt_dlhandle_interface *iface;
2035 } lt__interface_id;
2037 lt_dlinterface_id
2038 lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface)
2040 lt__interface_id *interface_id = (lt__interface_id *) lt__malloc (sizeof *interface_id);
2042 /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which
2043 can then be detected with lt_dlerror() if we return 0. */
2044 if (interface_id)
2046 interface_id->id_string = lt__strdup (id_string);
2047 if (!interface_id->id_string)
2048 FREE (interface_id);
2049 else
2050 interface_id->iface = iface;
2053 return (lt_dlinterface_id) interface_id;
2056 void lt_dlinterface_free (lt_dlinterface_id key)
2058 lt__interface_id *interface_id = (lt__interface_id *)key;
2059 FREE (interface_id->id_string);
2060 FREE (interface_id);
2063 void *
2064 lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data)
2066 int n_elements = 0;
2067 void *stale = (void *) 0;
2068 lt__handle *cur = (lt__handle *) handle;
2069 int i;
2071 if (cur->interface_data)
2072 while (cur->interface_data[n_elements].key)
2073 ++n_elements;
2075 for (i = 0; i < n_elements; ++i)
2077 if (cur->interface_data[i].key == key)
2079 stale = cur->interface_data[i].data;
2080 break;
2084 /* Ensure that there is enough room in this handle's interface_data
2085 array to accept a new element (and an empty end marker). */
2086 if (i == n_elements)
2088 lt_interface_data *temp
2089 = REALLOC (lt_interface_data, cur->interface_data, 2+ n_elements);
2091 if (!temp)
2093 stale = 0;
2094 goto done;
2097 cur->interface_data = temp;
2099 /* We only need this if we needed to allocate a new interface_data. */
2100 cur->interface_data[i].key = key;
2101 cur->interface_data[1+ i].key = 0;
2104 cur->interface_data[i].data = data;
2106 done:
2107 return stale;
2110 void *
2111 lt_dlcaller_get_data (lt_dlinterface_id key, lt_dlhandle handle)
2113 void *result = (void *) 0;
2114 lt__handle *cur = (lt__handle *) handle;
2116 /* Locate the index of the element with a matching KEY. */
2118 int i;
2119 for (i = 0; cur->interface_data[i].key; ++i)
2121 if (cur->interface_data[i].key == key)
2123 result = cur->interface_data[i].data;
2124 break;
2129 return result;
2132 const lt_dlinfo *
2133 lt_dlgetinfo (lt_dlhandle handle)
2135 if (!handle)
2137 LT__SETERROR (INVALID_HANDLE);
2138 return 0;
2141 return &(((lt__handle *) handle)->info);
2145 lt_dlhandle
2146 lt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place)
2148 lt__handle *handle = (lt__handle *) place;
2149 lt__interface_id *iterator = (lt__interface_id *) iface;
2151 assert (iface); /* iface is a required argument */
2153 if (!handle)
2154 handle = (lt__handle *) handles;
2155 else
2156 handle = handle->next;
2158 /* advance while the interface check fails */
2159 while (handle && iterator->iface
2160 && ((*iterator->iface) (handle, iterator->id_string) != 0))
2162 handle = handle->next;
2165 return (lt_dlhandle) handle;
2169 lt_dlhandle
2170 lt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name)
2172 lt_dlhandle handle = 0;
2174 assert (iface); /* iface is a required argument */
2176 while ((handle = lt_dlhandle_iterate (iface, handle)))
2178 lt__handle *cur = (lt__handle *) handle;
2179 if (cur && cur->info.name && streq (cur->info.name, module_name))
2180 break;
2183 return handle;
2188 lt_dlhandle_map (lt_dlinterface_id iface,
2189 int (*func) (lt_dlhandle handle, void *data), void *data)
2191 lt__interface_id *iterator = (lt__interface_id *) iface;
2192 lt__handle *cur = (lt__handle *) handles;
2194 assert (iface); /* iface is a required argument */
2196 while (cur)
2198 int errorcode = 0;
2200 /* advance while the interface check fails */
2201 while (cur && iterator->iface
2202 && ((*iterator->iface) (cur, iterator->id_string) != 0))
2204 cur = cur->next;
2207 if ((errorcode = (*func) (cur, data)) != 0)
2208 return errorcode;
2211 return 0;