dnscrypto-proxy: Update to release 1.3.0
[tomato.git] / release / src / router / dnscrypt / libltdl / ltdl.c
blob01853e05832b7c1d152bdc937e94b6664513996f
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. */
45 #undef LT_ARCHIVE_EXT
46 #define LT_ARCHIVE_EXT ".la"
48 /* max. filename length */
49 #if !defined(LT_FILENAME_MAX)
50 # define LT_FILENAME_MAX 1024
51 #endif
53 #if !defined(LT_LIBEXT)
54 # define LT_LIBEXT "a"
55 #endif
57 #if !defined(LT_LIBPREFIX)
58 # define LT_LIBPREFIX "lib"
59 #endif
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
70 lt_dlhandle... */
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;
82 #endif
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;
87 #endif
88 #if defined(LT_DLSEARCH_PATH)
89 static const char sys_dlsearch_path[] = LT_DLSEARCH_PATH;
90 #endif
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,
100 void *data2);
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,
110 void *data2);
111 static int find_handle_callback (char *filename, void *data,
112 void *ignored);
113 static int foreachfile_callback (char *filename, void *data1,
114 void *data2);
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,
124 lt_dlhandle *handle,
125 lt_dladvise advise);
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,
129 lt_dladvise advise);
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,
135 lt_dladvise advise);
136 static int tryall_dlopen (lt_dlhandle *handle,
137 const char *filename,
138 lt_dladvise padvise,
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,
144 const char *entry);
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,
148 const char *dir);
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,
158 lt_user_data data);
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!!). */
167 void
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. */
177 static int
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 */
185 static int
186 loader_init (lt_get_vtable *vtable_func, lt_user_data data)
188 const lt_dlvtable *vtable = 0;
189 int errors = 0;
191 if (vtable_func)
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);
206 ++errors;
210 return errors;
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)
217 LT_BEGIN_C_DECLS
218 LT_SCOPE const lt_dlvtable * get_vtable (lt_user_data data);
219 LT_END_C_DECLS
220 #ifdef HAVE_LIBDLLOADER
221 extern LT_DLSYM_CONST lt_dlsymlist preloaded_symbols[];
222 #endif
224 /* Initialize libltdl. */
226 lt_dlinit (void)
228 int errors = 0;
230 /* Initialize only at first call. */
231 if (++initialized == 1)
233 lt__alloc_die = lt__alloc_die_callback;
234 handles = 0;
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
239 compile time. */
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
245 if (!errors)
247 errors += lt_dlpreload (preloaded_symbols);
250 if (!errors)
252 errors += lt_dlpreload_open (LT_STR(LTDLOPEN), loader_init_callback);
254 #endif /* HAVE_LIBDLLOADER */
257 #ifdef LT_DEBUG_LOADERS
258 lt_dlloader_dump();
259 #endif
261 return errors;
265 lt_dlexit (void)
267 /* shut down libltdl */
268 lt_dlloader *loader = 0;
269 lt_dlhandle handle = handles;
270 int errors = 0;
272 if (!initialized)
274 LT__SETERROR (SHUTDOWN);
275 ++errors;
276 goto done;
279 /* shut down only at last call. */
280 if (--initialized == 0)
282 int level;
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;
295 while (cur)
297 lt_dlhandle tmp = cur;
298 cur = cur->next;
299 if (!LT_DLIS_RESIDENT (tmp))
301 saw_nonresident = 1;
302 if (tmp->info.ref_count <= level)
304 if (lt_dlclose (tmp))
306 ++errors;
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'. */
312 if (cur)
314 for (tmp = handles; tmp; tmp = tmp->next)
315 if (tmp == cur)
316 break;
317 if (! tmp)
318 cur = handles;
323 /* done if only resident modules are left */
324 if (!saw_nonresident)
325 break;
328 /* When removing loaders, we can only find out failure by testing
329 the error string, so avoid a spurious one from an earlier
330 failed command. */
331 if (!errors)
332 LT__SETERRORSTR (0);
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)))
342 FREE (vtable);
344 else
346 /* ignore errors due to resident modules */
347 const char *err;
348 LT__GETERROR (err);
349 if (err)
350 ++errors;
353 loader = next;
356 FREE(user_search_path);
359 done:
360 return errors;
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. */
367 static int
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;
373 int errors = 0;
375 #ifdef LT_DEBUG_LOADERS
376 fprintf (stderr, "tryall_dlopen (%s, %s)\n",
377 filename ? filename : "(null)",
378 vtable ? vtable->name : "(ALL)");
379 #endif
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)))
390 break;
394 if (handle)
396 ++handle->info.ref_count;
397 *phandle = handle;
398 goto done;
401 handle = *phandle;
402 if (filename)
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);
412 ++errors;
413 goto done;
414 } */
416 handle->info.filename = lt__strdup (filename);
417 if (!handle->info.filename)
419 ++errors;
420 goto done;
423 else
425 handle->info.filename = 0;
429 lt_dlloader loader = lt_dlloader_next (0);
430 const lt_dlvtable *loader_vtable;
434 if (vtable)
435 loader_vtable = vtable;
436 else
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)");
443 #endif
444 handle->module = (*loader_vtable->module_open) (loader_vtable->dlloader_data,
445 filename, advise);
446 #ifdef LT_DEBUG_LOADERS
447 fprintf (stderr, " Result: %s\n",
448 handle->module ? "Success" : "Failed");
449 #endif
451 if (handle->module != 0)
453 if (advise)
455 handle->info.is_resident = advise->is_resident;
456 handle->info.is_symglobal = advise->is_symglobal;
457 handle->info.is_symlocal = advise->is_symlocal;
459 break;
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
466 out! */
467 if ((vtable && !handle->module)
468 || (!vtable && !loader))
470 FREE (handle->info.filename);
471 ++errors;
472 goto done;
475 handle->vtable = loader_vtable;
478 LT__SETERRORSTR (saved_error);
480 done:
481 return errors;
485 static int
486 tryall_dlopen_module (lt_dlhandle *handle, const char *prefix,
487 const char *dirname, const char *dlname,
488 lt_dladvise advise)
490 int error = 0;
491 char *filename = 0;
492 size_t filename_len = 0;
493 size_t dirname_len = LT_STRLEN (dirname);
495 assert (handle);
496 assert (dirname);
497 assert (dlname);
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);
502 #endif
504 if (dirname_len > 0)
505 if (dirname[dirname_len -1] == '/')
506 --dirname_len;
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);
512 if (!filename)
513 return 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. */
520 if (prefix)
522 error += tryall_dlopen_module (handle, (const char *) 0,
523 prefix, filename, advise);
525 else if (tryall_dlopen (handle, filename, advise, 0) != 0)
527 ++error;
530 FREE (filename);
531 return error;
534 static int
535 find_module (lt_dlhandle *handle, const char *dir, const char *libdir,
536 const char *dlname, const char *old_name, int installed,
537 lt_dladvise advise)
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)
545 return 0;
548 /* Try to open the dynamic library. */
549 if (dlname)
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)
556 return 0;
559 /* try to open the not-installed module */
560 if (!installed)
562 if (tryall_dlopen_module (handle, dir, objdir,
563 dlname, advise) == 0)
564 return 0;
567 /* maybe it was moved to another directory */
569 if (dir && (tryall_dlopen_module (handle, (const char *) 0,
570 dir, dlname, advise) == 0))
571 return 0;
575 return 1;
579 static int
580 canonicalize_path (const char *path, char **pcanonical)
582 char *canonical = 0;
584 assert (path && *path);
585 assert (pcanonical);
587 canonical = MALLOC (char, 1+ LT_STRLEN (path));
588 if (!canonical)
589 return 1;
592 size_t dest = 0;
593 size_t src;
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
598 immediately. */
599 if (path[src] == LT_PATHSEP_CHAR)
601 if ((dest == 0)
602 || (path[1+ src] == LT_PATHSEP_CHAR)
603 || (path[1+ src] == LT_EOS_CHAR))
604 continue;
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)
611 #endif
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
618 NULL terminator. */
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)
623 #endif
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;
637 return 0;
640 static int
641 argzize_path (const char *path, char **pargz, size_t *pargz_len)
643 error_t error;
645 assert (path);
646 assert (pargz);
647 assert (pargz_len);
649 if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
651 switch (error)
653 case ENOMEM:
654 LT__SETERROR (NO_MEMORY);
655 break;
656 default:
657 LT__SETERROR (UNKNOWN);
658 break;
661 return 1;
664 return 0;
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. */
671 static int
672 foreach_dirinpath (const char *search_path, const char *base_name,
673 foreach_callback_func *func, void *data1, void *data2)
675 int result = 0;
676 size_t filenamesize = 0;
677 size_t lenbase = LT_STRLEN (base_name);
678 size_t argz_len = 0;
679 char *argz = 0;
680 char *filename = 0;
681 char *canonical = 0;
683 if (!search_path || !*search_path)
685 LT__SETERROR (FILE_NOT_FOUND);
686 goto cleanup;
689 if (canonicalize_path (search_path, &canonical) != 0)
690 goto cleanup;
692 if (argzize_path (canonical, &argz, &argz_len) != 0)
693 goto cleanup;
696 char *dir_name = 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)
703 FREE (filename);
704 filenamesize = 1+ lendir + 1+ lenbase; /* "/d" + '/' + "f" + '\0' */
705 filename = MALLOC (char, filenamesize);
706 if (!filename)
707 goto cleanup;
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)))
722 break;
727 cleanup:
728 FREE (argz);
729 FREE (canonical);
730 FREE (filename);
732 return result;
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. */
738 static int
739 find_file_callback (char *filename, void *data1, void *data2)
741 char **pdir = (char **) data1;
742 FILE **pfile = (FILE **) data2;
743 int is_done = 0;
745 assert (filename && *filename);
746 assert (pdir);
747 assert (pfile);
749 if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
751 char *dirend = strrchr (filename, '/');
753 if (dirend > filename)
754 *dirend = LT_EOS_CHAR;
756 FREE (*pdir);
757 *pdir = lt__strdup (filename);
758 is_done = (*pdir == 0) ? -1 : 1;
761 return is_done;
764 static FILE *
765 find_file (const char *search_path, const char *base_name, char **pdir)
767 FILE *file = 0;
769 foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
771 return file;
774 static int
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... */
782 if (notfound)
783 return 0;
785 /* Try to dlopen the file, but do not continue searching in any
786 case. */
787 if (tryall_dlopen (phandle, filename, advise, 0) != 0)
788 *phandle = 0;
790 return 1;
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. */
795 static lt_dlhandle *
796 find_handle (const char *search_path, const char *base_name,
797 lt_dlhandle *phandle, lt_dladvise advise)
799 if (!search_path)
800 return 0;
802 if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
803 phandle, advise))
804 return 0;
806 return phandle;
809 #if !defined(LTDL_DLOPEN_DEPLIBS)
810 static int
811 load_deplibs (lt_dlhandle handle, char * LT__UNUSED deplibs)
813 handle->depcount = 0;
814 return 0;
817 #else /* defined(LTDL_DLOPEN_DEPLIBS) */
818 static int
819 load_deplibs (lt_dlhandle handle, char *deplibs)
821 char *p, *save_search_path = 0;
822 int depcount = 0;
823 int i;
824 char **names = 0;
825 int errors = 0;
827 handle->depcount = 0;
829 if (!deplibs)
831 return errors;
833 ++errors;
835 if (user_search_path)
837 save_search_path = lt__strdup (user_search_path);
838 if (!save_search_path)
839 goto cleanup;
842 /* extract search paths and count deplibs */
843 p = deplibs;
844 while (*p)
846 if (!isspace ((unsigned char) *p))
848 char *end = p+1;
849 while (*end && !isspace((unsigned char) *end))
851 ++end;
854 if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
856 char save = *end;
857 *end = 0; /* set a temporary string terminator */
858 if (lt_dladdsearchdir(p+2))
860 goto cleanup;
862 *end = save;
864 else
866 ++depcount;
869 p = end;
871 else
873 ++p;
878 if (!depcount)
880 errors = 0;
881 goto cleanup;
884 names = MALLOC (char *, depcount);
885 if (!names)
886 goto cleanup;
888 /* now only extract the actual deplibs */
889 depcount = 0;
890 p = deplibs;
891 while (*p)
893 if (isspace ((unsigned char) *p))
895 ++p;
897 else
899 char *end = p+1;
900 while (*end && !isspace ((unsigned char) *end))
902 ++end;
905 if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
907 char *name;
908 char save = *end;
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);
914 if (name)
915 sprintf (name, "lib%s", p+2);
917 else
918 name = lt__strdup(p);
920 if (!name)
921 goto cleanup_names;
923 names[depcount++] = name;
924 *end = save;
926 p = end;
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. */
935 if (depcount)
937 lt_dlhandle cur = handle;
938 int j = 0;
940 cur->deplibs = MALLOC (lt_dlhandle, depcount);
941 if (!cur->deplibs)
942 goto cleanup_names;
944 for (i = 0; i < depcount; ++i)
946 cur->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
947 if (cur->deplibs[j])
949 ++j;
953 cur->depcount = j; /* Number of successfully loaded deplibs */
954 errors = 0;
957 cleanup_names:
958 for (i = 0; i < depcount; ++i)
960 FREE (names[i]);
963 cleanup:
964 FREE (names);
965 /* restore the old search path */
966 if (save_search_path) {
967 MEMREASSIGN (user_search_path, save_search_path);
970 return errors;
972 #endif /* defined(LTDL_DLOPEN_DEPLIBS) */
974 static int
975 unload_deplibs (lt_dlhandle handle)
977 int i;
978 int errors = 0;
979 lt_dlhandle cur = handle;
981 if (cur->depcount)
983 for (i = 0; i < cur->depcount; ++i)
985 if (!LT_DLIS_RESIDENT (cur->deplibs[i]))
987 errors += lt_dlclose (cur->deplibs[i]);
990 FREE (cur->deplibs);
993 return errors;
996 static int
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);
1003 char *tmp;
1005 FREE (*dest);
1007 if (!end || end == str)
1008 return 1;
1010 if (len > 3 && str[0] == '\'')
1012 tmp = MALLOC (char, end - str);
1013 if (!tmp)
1014 return 1;
1016 memcpy(tmp, &str[1], (end - str) - 1);
1017 tmp[(end - str) - 1] = LT_EOS_CHAR;
1018 *dest = tmp;
1020 else
1022 *dest = 0;
1025 return 0;
1028 /* Read the .la file FILE. */
1029 static int
1030 parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs,
1031 char **old_name, int *installed)
1033 int errors = 0;
1034 size_t line_len = LT_FILENAME_MAX;
1035 char * line = MALLOC (char, line_len);
1037 if (!line)
1039 LT__SETERROR (FILE_NOT_FOUND);
1040 return 1;
1043 while (!feof (file))
1045 line[line_len-2] = '\0';
1046 if (!fgets (line, (int) line_len, file))
1048 break;
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);
1057 if (!line)
1059 ++errors;
1060 goto cleanup;
1062 line[line_len * 2 - 2] = '\0';
1063 if (!fgets (&line[line_len -1], (int) line_len +1, file))
1065 break;
1067 line_len *= 2;
1070 if (line[0] == '\n' || line[0] == '#')
1072 continue;
1075 #undef STR_DLNAME
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
1091 in libdir. */
1092 #undef STR_LIBDIR
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]);
1097 #ifdef __WINDOWS__
1098 /* Disallow following unix-style paths on MinGW. */
1099 if (*libdir && (**libdir == '/' || **libdir == '\\'))
1100 **libdir = '\0';
1101 #endif
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"))
1113 *installed = 1;
1115 else if (streq (line, "installed=no\n"))
1117 *installed = 0;
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)
1125 char *last_libname;
1126 errors += trim (dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
1127 if (!errors
1128 && *dlname
1129 && (last_libname = strrchr (*dlname, ' ')) != 0)
1131 last_libname = lt__strdup (last_libname + 1);
1132 if (!last_libname)
1134 ++errors;
1135 goto cleanup;
1137 MEMREASSIGN (*dlname, last_libname);
1141 if (errors)
1142 break;
1144 cleanup:
1145 FREE (line);
1146 return errors;
1150 /* Try to open FILENAME as a module. */
1151 static int
1152 try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
1153 lt_dladvise advise)
1155 const char * saved_error = 0;
1156 char * archive_name = 0;
1157 char * canonical = 0;
1158 char * base_name = 0;
1159 char * dir = 0;
1160 char * name = 0;
1161 char * attempt = 0;
1162 int errors = 0;
1163 lt_dlhandle newhandle;
1165 assert (phandle);
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)");
1172 #endif
1174 LT__GETERROR (saved_error);
1176 /* dlopen self? */
1177 if (!filename)
1179 *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1180 if (*phandle == 0)
1181 return 1;
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)
1190 FREE (*phandle);
1191 return 1;
1194 goto register_handle;
1197 assert (filename && *filename);
1199 if (ext)
1201 attempt = MALLOC (char, LT_STRLEN (filename) + LT_STRLEN (ext) + 1);
1202 if (!attempt)
1203 return 1;
1205 sprintf(attempt, "%s%s", filename, ext);
1207 else
1209 attempt = lt__strdup (filename);
1210 if (!attempt)
1211 return 1;
1214 /* Doing this immediately allows internal functions to safely
1215 assume only canonicalized paths are passed. */
1216 if (canonicalize_path (attempt, &canonical) != 0)
1218 ++errors;
1219 goto cleanup;
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, '/');
1225 if (base_name)
1227 size_t dirlen = (1+ base_name) - canonical;
1229 dir = MALLOC (char, 1+ dirlen);
1230 if (!dir)
1232 ++errors;
1233 goto cleanup;
1236 strncpy (dir, canonical, dirlen);
1237 dir[dirlen] = LT_EOS_CHAR;
1239 ++base_name;
1241 else
1242 MEMREASSIGN (base_name, canonical);
1244 assert (base_name && *base_name);
1246 ext = strrchr (base_name, '.');
1247 if (!ext)
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);
1254 if (!name)
1256 ++errors;
1257 goto cleanup;
1260 /* canonicalize the module name */
1262 int i;
1263 for (i = 0; i < ext - base_name; ++i)
1265 if (isalnum ((unsigned char)(base_name[i])))
1267 name[i] = base_name[i];
1269 else
1271 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. */
1279 if (!dir)
1281 const lt_dlvtable *vtable = lt_dlloader_find ("lt_preopen");
1283 if (vtable)
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))
1291 ++errors;
1292 goto cleanup;
1294 newhandle = *phandle;
1296 /* Preloaded modules are always named according to their old
1297 archive name. */
1298 if (strncmp(name, "lib", 3) == 0)
1300 sprintf (archive_name, "%s%s.%s", libprefix, name + 3, libext);
1302 else
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. */
1314 FREE (*phandle);
1315 newhandle = NULL;
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)
1323 goto cleanup;
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 */
1330 FILE * file = 0;
1331 char * dlname = 0;
1332 char * old_name = 0;
1333 char * libdir = 0;
1334 char * deplibs = 0;
1336 /* if we can't find the installed flag, it is probably an
1337 installed libtool archive, produced with an old version
1338 of libtool */
1339 int installed = 1;
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. */
1345 if (!dir)
1347 const char *search_path = user_search_path;
1349 if (search_path)
1350 file = find_file (user_search_path, base_name, &dir);
1352 if (!file)
1354 search_path = getenv (LTDL_SEARCHPATH_VAR);
1355 if (search_path)
1356 file = find_file (search_path, base_name, &dir);
1359 #if defined(LT_MODULE_PATH_VAR)
1360 if (!file)
1362 search_path = getenv (LT_MODULE_PATH_VAR);
1363 if (search_path)
1364 file = find_file (search_path, base_name, &dir);
1366 #endif
1367 #if defined(LT_DLSEARCH_PATH)
1368 if (!file && *sys_dlsearch_path)
1370 file = find_file (sys_dlsearch_path, base_name, &dir);
1372 #endif
1374 else
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. */
1381 if (!file)
1383 LT__SETERROR (FILE_NOT_FOUND);
1384 ++errors;
1385 goto cleanup;
1388 /* read the .la file */
1389 if (parse_dotla_file(file, &dlname, &libdir, &deplibs,
1390 &old_name, &installed) != 0)
1391 ++errors;
1393 fclose (file);
1395 /* allocate the handle */
1396 *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1397 if (*phandle == 0)
1398 ++errors;
1400 if (errors)
1402 FREE (dlname);
1403 FREE (old_name);
1404 FREE (libdir);
1405 FREE (deplibs);
1406 FREE (*phandle);
1407 goto cleanup;
1410 assert (*phandle);
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,
1417 installed, advise))
1419 unload_deplibs (*phandle);
1420 ++errors;
1423 else
1425 ++errors;
1428 FREE (dlname);
1429 FREE (old_name);
1430 FREE (libdir);
1431 FREE (deplibs);
1433 if (errors)
1435 FREE (*phandle);
1436 goto cleanup;
1439 if (*phandle != newhandle)
1441 unload_deplibs (*phandle);
1444 else
1446 /* not a libtool module */
1447 *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1448 if (*phandle == 0)
1450 ++errors;
1451 goto cleanup;
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,
1461 &newhandle, advise)
1462 && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
1463 &newhandle, advise)
1464 #if defined(LT_MODULE_PATH_VAR)
1465 && !find_handle (getenv (LT_MODULE_PATH_VAR), base_name,
1466 &newhandle, advise)
1467 #endif
1468 #if defined(LT_DLSEARCH_PATH)
1469 && !find_handle (sys_dlsearch_path, base_name,
1470 &newhandle, advise)
1471 #endif
1474 if (tryall_dlopen (&newhandle, attempt, advise, 0) != 0)
1476 newhandle = NULL;
1480 if (!newhandle)
1482 FREE (*phandle);
1483 ++errors;
1484 goto cleanup;
1488 register_handle:
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;
1497 handles = *phandle;
1500 LT__SETERRORSTR (saved_error);
1502 cleanup:
1503 FREE (dir);
1504 FREE (attempt);
1505 FREE (name);
1506 if (!canonical) /* was MEMREASSIGNed */
1507 FREE (base_name);
1508 FREE (canonical);
1509 FREE (archive_name);
1511 return errors;
1515 /* If the last error message stored was `FILE_NOT_FOUND', then return
1516 non-zero. */
1517 static int
1518 file_not_found (void)
1520 const char *error = 0;
1522 LT__GETERROR (error);
1523 if (error == LT__STRERROR (FILE_NOT_FOUND))
1524 return 1;
1526 return 0;
1530 /* Unless FILENAME already bears a suitable library extension, then
1531 return 0. */
1532 static int
1533 has_library_ext (const char *filename)
1535 const char * ext = 0;
1537 assert (filename);
1539 ext = strrchr (filename, '.');
1541 if (ext && ((streq (ext, archive_ext))
1542 #if defined(LT_MODULE_EXT)
1543 || (streq (ext, shlib_ext))
1544 #endif
1545 #if defined(LT_SHARED_EXT)
1546 || (streq (ext, shared_ext))
1547 #endif
1550 return 1;
1553 return 0;
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));
1563 *padvise = advise;
1564 return (advise ? 0 : 1);
1568 lt_dladvise_destroy (lt_dladvise *padvise)
1570 if (padvise)
1571 FREE(*padvise);
1572 return 0;
1576 lt_dladvise_ext (lt_dladvise *padvise)
1578 assert (padvise && *padvise);
1579 (*padvise)->try_ext = 1;
1580 return 0;
1584 lt_dladvise_resident (lt_dladvise *padvise)
1586 assert (padvise && *padvise);
1587 (*padvise)->is_resident = 1;
1588 return 0;
1592 lt_dladvise_local (lt_dladvise *padvise)
1594 assert (padvise && *padvise);
1595 (*padvise)->is_symlocal = 1;
1596 return 0;
1600 lt_dladvise_global (lt_dladvise *padvise)
1602 assert (padvise && *padvise);
1603 (*padvise)->is_symglobal = 1;
1604 return 0;
1608 lt_dladvise_preload (lt_dladvise *padvise)
1610 assert (padvise && *padvise);
1611 (*padvise)->try_preload_only = 1;
1612 return 0;
1615 /* Libtool-1.5.x interface for loading a new module named FILENAME. */
1616 lt_dlhandle
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
1626 instead. */
1627 lt_dlhandle
1628 lt_dlopenext (const char *filename)
1630 lt_dlhandle handle = 0;
1631 lt_dladvise advise;
1633 if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise))
1634 handle = lt_dlopenadvise (filename, advise);
1636 lt_dladvise_destroy (&advise);
1637 return handle;
1641 lt_dlhandle
1642 lt_dlopenadvise (const char *filename, lt_dladvise advise)
1644 lt_dlhandle handle = 0;
1645 int errors = 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);
1654 return 0;
1657 if (!filename
1658 || !advise
1659 || !advise->try_ext
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)
1665 return 0;
1667 return handle;
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 ()))
1681 return handle;
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 ()))
1691 return handle;
1692 #endif
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 ()))
1702 return handle;
1703 #endif
1706 /* Still here? Then we really did fail to locate any of the file
1707 names we tried. */
1708 LT__SETERROR (FILE_NOT_FOUND);
1709 return 0;
1713 static int
1714 lt_argz_insert (char **pargz, size_t *pargz_len, char *before,
1715 const char *entry)
1717 error_t error;
1719 /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
1720 pargz_len, NULL, entry) failed with EINVAL. */
1721 if (before)
1722 error = argz_insert (pargz, pargz_len, before, entry);
1723 else
1724 error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry));
1726 if (error)
1728 switch (error)
1730 case ENOMEM:
1731 LT__SETERROR (NO_MEMORY);
1732 break;
1733 default:
1734 LT__SETERROR (UNKNOWN);
1735 break;
1737 return 1;
1740 return 0;
1743 static int
1744 lt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry)
1746 char *before = 0;
1748 assert (pargz);
1749 assert (pargz_len);
1750 assert (entry && *entry);
1752 if (*pargz)
1753 while ((before = argz_next (*pargz, *pargz_len, before)))
1755 int cmp = strcmp (entry, before);
1757 if (cmp < 0) break;
1758 if (cmp == 0) return 0; /* No duplicates! */
1761 return lt_argz_insert (pargz, pargz_len, before, entry);
1764 static int
1765 lt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam,
1766 struct dirent *dp)
1768 char *buf = 0;
1769 size_t buf_len = 0;
1770 char *end = 0;
1771 size_t end_offset = 0;
1772 size_t dir_len = 0;
1773 int errors = 0;
1775 assert (pargz);
1776 assert (pargz_len);
1777 assert (dp);
1779 dir_len = LT_STRLEN (dirnam);
1780 end = dp->d_name + D_NAMLEN(dp);
1782 /* Ignore version numbers. */
1784 char *p;
1785 for (p = end; p -1 > dp->d_name; --p)
1786 if (strchr (".0123456789", p[-1]) == 0)
1787 break;
1789 if (*p == '.')
1790 end = p;
1793 /* Ignore filename extension. */
1795 char *p;
1796 for (p = end -1; p > dp->d_name; --p)
1797 if (*p == '.')
1799 end = p;
1800 break;
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);
1808 if (!buf)
1809 return ++errors;
1811 assert (buf);
1813 strcpy (buf, dirnam);
1814 strcat (buf, "/");
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)
1820 ++errors;
1822 FREE (buf);
1824 return errors;
1827 static int
1828 list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len)
1830 DIR *dirp = 0;
1831 int errors = 0;
1833 assert (dirnam && *dirnam);
1834 assert (pargz);
1835 assert (pargz_len);
1836 assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
1838 dirp = opendir (dirnam);
1839 if (dirp)
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))
1847 ++errors;
1848 break;
1851 closedir (dirp);
1853 else
1854 ++errors;
1856 return errors;
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). */
1862 static int
1863 foreachfile_callback (char *dirname, void *data1, void *data2)
1865 file_worker_func *func = *(file_worker_func **) data1;
1867 int is_done = 0;
1868 char *argz = 0;
1869 size_t argz_len = 0;
1871 if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
1872 goto cleanup;
1873 if (!argz)
1874 goto cleanup;
1877 char *filename = 0;
1878 while ((filename = argz_next (argz, argz_len, filename)))
1879 if ((is_done = (*func) (filename, data2)))
1880 break;
1883 cleanup:
1884 FREE (argz);
1886 return is_done;
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),
1899 void *data)
1901 int is_done = 0;
1902 file_worker_func **fpptr = &func;
1904 if (search_path)
1906 /* If a specific path was passed, search only the directories
1907 listed in it. */
1908 is_done = foreach_dirinpath (search_path, 0,
1909 foreachfile_callback, fpptr, data);
1911 else
1913 /* Otherwise search the default paths. */
1914 is_done = foreach_dirinpath (user_search_path, 0,
1915 foreachfile_callback, fpptr, data);
1916 if (!is_done)
1918 is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0,
1919 foreachfile_callback, fpptr, data);
1922 #if defined(LT_MODULE_PATH_VAR)
1923 if (!is_done)
1925 is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0,
1926 foreachfile_callback, fpptr, data);
1928 #endif
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);
1935 #endif
1938 return is_done;
1942 lt_dlclose (lt_dlhandle handle)
1944 lt_dlhandle cur, last;
1945 int errors = 0;
1947 /* check whether the handle is valid */
1948 last = cur = handles;
1949 while (cur && handle != cur)
1951 last = cur;
1952 cur = cur->next;
1955 if (!cur)
1957 LT__SETERROR (INVALID_HANDLE);
1958 ++errors;
1959 goto done;
1962 cur = 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
1968 moment). */
1969 if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur))
1971 lt_user_data data = cur->vtable->dlloader_data;
1973 if (cur != handles)
1975 last->next = cur->next;
1977 else
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);
1990 FREE (cur);
1992 goto done;
1995 if (LT_DLIS_RESIDENT (handle))
1997 LT__SETERROR (CLOSE_RESIDENT_MODULE);
1998 ++errors;
2001 done:
2002 return errors;
2005 void *
2006 lt_dlsym (lt_dlhandle place, const char *symbol)
2008 size_t lensym;
2009 char lsym[LT_SYMBOL_LENGTH];
2010 char *sym;
2011 void *address;
2012 lt_user_data data;
2013 lt_dlhandle handle;
2015 if (!place)
2017 LT__SETERROR (INVALID_HANDLE);
2018 return 0;
2021 handle = place;
2023 if (!symbol)
2025 LT__SETERROR (SYMBOL_NOT_FOUND);
2026 return 0;
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)
2034 sym = lsym;
2036 else
2038 sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
2039 if (!sym)
2041 LT__SETERROR (BUFFER_OVERFLOW);
2042 return 0;
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);
2059 else
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);
2069 if (address)
2071 if (sym != lsym)
2073 FREE (sym);
2075 return address;
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);
2086 else
2088 strcpy(sym, symbol);
2091 address = handle->vtable->find_sym (data, handle->module, sym);
2092 if (sym != lsym)
2094 FREE (sym);
2097 return address;
2100 const char *
2101 lt_dlerror (void)
2103 const char *error;
2105 LT__GETERROR (error);
2106 LT__SETERRORSTR (0);
2108 return error;
2111 static int
2112 lt_dlpath_insertdir (char **ppath, char *before, const char *dir)
2114 int errors = 0;
2115 char *canonical = 0;
2116 char *argz = 0;
2117 size_t argz_len = 0;
2119 assert (ppath);
2120 assert (dir && *dir);
2122 if (canonicalize_path (dir, &canonical) != 0)
2124 ++errors;
2125 goto cleanup;
2128 assert (canonical && *canonical);
2130 /* If *PPATH is empty, set it to DIR. */
2131 if (*ppath == 0)
2133 assert (!before); /* BEFORE cannot be set without PPATH. */
2134 assert (dir); /* Without DIR, don't call this function! */
2136 *ppath = lt__strdup (dir);
2137 if (*ppath == 0)
2138 ++errors;
2140 goto cleanup;
2143 assert (ppath && *ppath);
2145 if (argzize_path (*ppath, &argz, &argz_len) != 0)
2147 ++errors;
2148 goto cleanup;
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. */
2156 if (before)
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)
2166 ++errors;
2167 goto cleanup;
2170 argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
2171 MEMREASSIGN(*ppath, argz);
2173 cleanup:
2174 FREE (argz);
2175 FREE (canonical);
2177 return errors;
2181 lt_dladdsearchdir (const char *search_dir)
2183 int errors = 0;
2185 if (search_dir && *search_dir)
2187 if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
2188 ++errors;
2191 return errors;
2195 lt_dlinsertsearchdir (const char *before, const char *search_dir)
2197 int errors = 0;
2199 if (before)
2201 if ((before < user_search_path)
2202 || (before >= user_search_path + LT_STRLEN (user_search_path)))
2204 LT__SETERROR (INVALID_POSITION);
2205 return 1;
2209 if (search_dir && *search_dir)
2211 if (lt_dlpath_insertdir (&user_search_path,
2212 (char *) before, search_dir) != 0)
2214 ++errors;
2218 return errors;
2222 lt_dlsetsearchpath (const char *search_path)
2224 int errors = 0;
2226 FREE (user_search_path);
2228 if (!search_path || !LT_STRLEN (search_path))
2230 return errors;
2233 if (canonicalize_path (search_path, &user_search_path) != 0)
2234 ++errors;
2236 return errors;
2239 const char *
2240 lt_dlgetsearchpath (void)
2242 const char *saved_path;
2244 saved_path = user_search_path;
2246 return saved_path;
2250 lt_dlmakeresident (lt_dlhandle handle)
2252 int errors = 0;
2254 if (!handle)
2256 LT__SETERROR (INVALID_HANDLE);
2257 ++errors;
2259 else
2261 handle->info.is_resident = 1;
2264 return errors;
2268 lt_dlisresident (lt_dlhandle handle)
2270 if (!handle)
2272 LT__SETERROR (INVALID_HANDLE);
2273 return -1;
2276 return LT_DLIS_RESIDENT (handle);
2281 /* --- MODULE INFORMATION --- */
2283 typedef struct {
2284 const char *id_string;
2285 lt_dlhandle_interface *iface;
2286 } lt__interface_id;
2288 lt_dlinterface_id
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. */
2295 if (interface_id)
2297 interface_id->id_string = lt__strdup (id_string);
2298 if (!interface_id->id_string)
2299 FREE (interface_id);
2300 else
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);
2314 void *
2315 lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data)
2317 int n_elements = 0;
2318 void *stale = (void *) 0;
2319 lt_dlhandle cur = handle;
2320 int i;
2322 if (cur->interface_data)
2323 while (cur->interface_data[n_elements].key)
2324 ++n_elements;
2326 for (i = 0; i < n_elements; ++i)
2328 if (cur->interface_data[i].key == key)
2330 stale = cur->interface_data[i].data;
2331 break;
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);
2342 if (!temp)
2344 stale = 0;
2345 goto done;
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;
2357 done:
2358 return stale;
2361 void *
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)
2370 int i;
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;
2376 break;
2381 return result;
2384 const lt_dlinfo *
2385 lt_dlgetinfo (lt_dlhandle handle)
2387 if (!handle)
2389 LT__SETERROR (INVALID_HANDLE);
2390 return 0;
2393 return &(handle->info);
2397 lt_dlhandle
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 */
2405 if (!handle)
2406 handle = handles;
2407 else
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;
2417 return handle;
2421 lt_dlhandle
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))
2432 break;
2435 return handle;
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 */
2448 while (cur)
2450 int errorcode = 0;
2452 /* advance while the interface check fails */
2453 while (cur && iterator->iface
2454 && ((*iterator->iface) (cur, iterator->id_string) != 0))
2456 cur = cur->next;
2459 if ((errorcode = (*func) (cur, data)) != 0)
2460 return errorcode;
2463 return 0;