1 /* ltdl.c -- system independent dlopen wrapper
2 Copyright (C) 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
3 Originally by Thomas Tanner <tanner@ffii.org>
4 This file is part of GNU Libtool.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 As a special exception to the GNU Lesser General Public License,
12 if you distribute this file as part of a program or library that
13 is built using GNU libtool, you may include it under the same
14 distribution terms that you use for the rest of that program.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Lesser General Public License for more details.
21 You should have received a copy of the GNU Lesser General Public
22 License along with this library; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
40 /* Include the header defining malloc. On K&R C compilers,
41 that's <malloc.h>, on ANSI C and ISO C compilers, that's <stdlib.h>. */
78 #undef LT_USE_POSIX_DIRENT
83 # define LT_USE_POSIX_DIRENT
84 # endif /* HAVE_DIRENT_H */
85 # endif /* HAVE_READDIR */
86 # endif /* HAVE_OPENDIR */
87 #endif /* HAVE_CLOSEDIR */
90 #undef LT_USE_WINDOWS_DIRENT_EMULATION
91 #ifndef LT_USE_POSIX_DIRENT
93 # define LT_USE_WINDOWS_DIRENT_EMULATION
94 # endif /* __WINDOWS__ */
95 #endif /* LT_USE_POSIX_DIRENT */
98 #ifdef LT_USE_POSIX_DIRENT
100 # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
102 # ifdef LT_USE_WINDOWS_DIRENT_EMULATION
103 # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
105 # define dirent direct
106 # define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
108 # include <sys/ndir.h>
111 # include <sys/dir.h>
126 # define assert(arg) ((void) 0)
132 # include <dmalloc.h>
138 /* --- WINDOWS SUPPORT --- */
142 # define LT_GLOBAL_DATA __declspec(dllexport)
144 # define LT_GLOBAL_DATA
147 /* fopen() mode flags for reading a text file */
148 #undef LT_READTEXT_MODE
150 # define LT_READTEXT_MODE "rt"
152 # define LT_READTEXT_MODE "r"
155 #ifdef LT_USE_WINDOWS_DIRENT_EMULATION
159 #define dirent lt_dirent
171 WIN32_FIND_DATA Win32FindData;
173 struct dirent file_info;
176 #endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
179 /* --- MANIFEST CONSTANTS --- */
182 /* Standard libltdl search path environment variable name */
183 #undef LTDL_SEARCHPATH_VAR
184 #define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
186 /* Standard libtool archive file extension. */
187 #undef LTDL_ARCHIVE_EXT
188 #define LTDL_ARCHIVE_EXT ".la"
190 /* max. filename length */
191 #ifndef LT_FILENAME_MAX
192 # define LT_FILENAME_MAX 1024
195 /* This is the maximum symbol size that won't require malloc/free */
196 #undef LT_SYMBOL_LENGTH
197 #define LT_SYMBOL_LENGTH 128
199 /* This accounts for the _LTX_ separator */
200 #undef LT_SYMBOL_OVERHEAD
201 #define LT_SYMBOL_OVERHEAD 5
206 /* --- MEMORY HANDLING --- */
209 /* These are the functions used internally. In addition to making
210 use of the associated function pointers above, they also perform
212 static char *lt_estrdup LT_PARAMS((const char *str));
213 static lt_ptr lt_emalloc LT_PARAMS((size_t size));
214 static lt_ptr lt_erealloc LT_PARAMS((lt_ptr addr, size_t size));
216 /* static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size)); */
217 #define rpl_realloc realloc
219 /* These are the pointers that can be changed by the caller: */
220 LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size))
221 = (lt_ptr (*) LT_PARAMS((size_t))) malloc;
222 LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size))
223 = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc;
224 LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr))
225 = (void (*) LT_PARAMS((lt_ptr))) free;
227 /* The following macros reduce the amount of typing needed to cast
231 #define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
232 #define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
233 #define LT_DLFREE(p) \
234 LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END
236 #define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp)))
237 #define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp)))
241 #define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
242 #define LT_DLREALLOC(tp, p, n) ((tp *) lt_dlrealloc ((p), (n) * sizeof(tp)))
243 #define LT_DLFREE(p) \
244 LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
246 #define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp)))
247 #define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
251 #define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \
252 if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; } \
256 /* --- REPLACEMENT FUNCTIONS --- */
260 #define strdup rpl_strdup
262 static char *strdup LT_PARAMS((const char *str));
272 tmp = LT_DLMALLOC (char, 1+ strlen (str));
286 #define strcmp rpl_strcmp
288 static int strcmp LT_PARAMS((const char *str1, const char *str2));
302 for (;*str1 && *str2; ++str1, ++str2)
308 return (int)(*str1 - *str2);
316 # define strchr index
318 # define strchr rpl_strchr
320 static const char *strchr LT_PARAMS((const char *str, int ch));
329 for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p)
332 return (*p == (char)ch) ? p : 0;
336 #endif /* !HAVE_STRCHR */
342 # define strrchr rindex
344 # define strrchr rpl_strrchr
346 static const char *strrchr LT_PARAMS((const char *str, int ch));
353 const char *p, *q = 0;
355 for (p = str; *p != LT_EOS_CHAR; ++p)
369 /* NOTE: Neither bcopy nor the memcpy implementation below can
370 reliably handle copying in overlapping areas of memory. Use
371 memmove (for which there is a fallback implmentation below)
372 if you need that behaviour. */
376 # define memcpy(dest, src, size) bcopy (src, dest, size)
378 # define memcpy rpl_memcpy
380 static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
383 memcpy (dest, src, size)
388 const char * s = src;
392 for (i = 0; i < size; ++i)
400 # endif /* !HAVE_BCOPY */
401 #endif /* !HAVE_MEMCPY */
404 # define memmove rpl_memmove
406 static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
409 memmove (dest, src, size)
414 const char * s = src;
419 for (i = 0; i < size; ++i)
423 else if (d > s && size > 0)
424 for (i = size -1; ; --i)
434 #endif /* !HAVE_MEMMOVE */
436 #ifdef LT_USE_WINDOWS_DIRENT_EMULATION
438 static void closedir LT_PARAMS((DIR *entry));
444 assert(entry != (DIR *) NULL);
445 FindClose(entry->hSearch);
446 lt_dlfree((lt_ptr)entry);
450 static DIR * opendir LT_PARAMS((const char *path));
456 char file_specification[LT_FILENAME_MAX];
459 assert(path != (char *) NULL);
460 (void) strncpy(file_specification,path,LT_FILENAME_MAX-1);
461 (void) strcat(file_specification,"\\");
462 entry = LT_DLMALLOC (DIR,sizeof(DIR));
463 if (entry != (DIR *) 0)
465 entry->firsttime = TRUE;
466 entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData);
468 if (entry->hSearch == INVALID_HANDLE_VALUE)
470 (void) strcat(file_specification,"\\*.*");
471 entry->hSearch = FindFirstFile(file_specification,&entry->Win32FindData);
472 if (entry->hSearch == INVALID_HANDLE_VALUE)
482 static struct dirent *readdir LT_PARAMS((DIR *entry));
484 static struct dirent *readdir(entry)
490 if (entry == (DIR *) 0)
491 return((struct dirent *) 0);
492 if (!entry->firsttime)
494 status = FindNextFile(entry->hSearch,&entry->Win32FindData);
496 return((struct dirent *) 0);
498 entry->firsttime = FALSE;
499 (void) strncpy(entry->file_info.d_name,entry->Win32FindData.cFileName,
501 entry->file_info.d_namlen = strlen(entry->file_info.d_name);
502 return(&entry->file_info);
505 #endif /* LT_USE_WINDOWS_DIRENT_EMULATION */
507 /* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
508 ``realloc is not entirely portable''
509 In any case we want to use the allocator supplied by the user without
510 burdening them with an lt_dlrealloc function pointer to maintain.
511 Instead implement our own version (with known boundary conditions)
512 using lt_dlmalloc and lt_dlfree. */
515 #define realloc rpl_realloc
518 /* You can't (re)define realloc unless you also (re)define malloc.
519 Right now, this code uses the size of the *destination* to decide
520 how much to copy. That's not right, but you can't know the size
521 of the source unless you know enough about, or wrote malloc. So
522 this code is disabled... */
531 /* For zero or less bytes, free the original memory */
541 /* Allow reallocation of a NULL pointer. */
542 return lt_dlmalloc (size);
546 /* Allocate a new block, copy and free the old block. */
547 lt_ptr mem = lt_dlmalloc (size);
551 memcpy (mem, ptr, size);
555 /* Note that the contents of PTR are not damaged if there is
556 insufficient memory to realloc. */
563 #if ! HAVE_ARGZ_APPEND
564 # define argz_append rpl_argz_append
566 static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len,
567 const char *buf, size_t buf_len));
570 argz_append (pargz, pargz_len, buf, buf_len)
581 assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
583 /* If nothing needs to be appended, no more work is required. */
587 /* Ensure there is enough room to append BUF_LEN. */
588 argz_len = *pargz_len + buf_len;
589 argz = LT_DLREALLOC (char, *pargz, argz_len);
593 /* Copy characters from BUF after terminating '\0' in ARGZ. */
594 memcpy (argz + *pargz_len, buf, buf_len);
596 /* Assign new values. */
598 *pargz_len = argz_len;
602 #endif /* !HAVE_ARGZ_APPEND */
605 #if ! HAVE_ARGZ_CREATE_SEP
606 # define argz_create_sep rpl_argz_create_sep
608 static error_t argz_create_sep LT_PARAMS((const char *str, int delim,
609 char **pargz, size_t *pargz_len));
612 argz_create_sep (str, delim, pargz, pargz_len)
625 /* Make a copy of STR, but replacing each occurence of
627 argz_len = 1+ LT_STRLEN (str);
633 argz = LT_DLMALLOC (char, argz_len);
637 for (p = str, q = argz; *p != LT_EOS_CHAR; ++p)
641 /* Ignore leading delimiters, and fold consecutive
642 delimiters in STR into a single '\0' in ARGZ. */
643 if ((q > argz) && (q[-1] != LT_EOS_CHAR))
651 /* Copy terminating LT_EOS_CHAR. */
655 /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */
659 /* Assign new values. */
661 *pargz_len = argz_len;
665 #endif /* !HAVE_ARGZ_CREATE_SEP */
668 #if ! HAVE_ARGZ_INSERT
669 # define argz_insert rpl_argz_insert
671 static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len,
672 char *before, const char *entry));
675 argz_insert (pargz, pargz_len, before, entry)
683 assert (entry && *entry);
685 /* No BEFORE address indicates ENTRY should be inserted after the
686 current last element. */
688 return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry));
690 /* This probably indicates a programmer error, but to preserve
691 semantics, scan back to the start of an entry if BEFORE points
692 into the middle of it. */
693 while ((before > *pargz) && (before[-1] != LT_EOS_CHAR))
697 size_t entry_len = 1+ LT_STRLEN (entry);
698 size_t argz_len = *pargz_len + entry_len;
699 size_t offset = before - *pargz;
700 char *argz = LT_DLREALLOC (char, *pargz, argz_len);
705 /* Make BEFORE point to the equivalent offset in ARGZ that it
706 used to have in *PARGZ incase realloc() moved the block. */
707 before = argz + offset;
709 /* Move the ARGZ entries starting at BEFORE up into the new
710 space at the end -- making room to copy ENTRY into the
712 memmove (before + entry_len, before, *pargz_len - offset);
713 memcpy (before, entry, entry_len);
715 /* Assign new values. */
717 *pargz_len = argz_len;
722 #endif /* !HAVE_ARGZ_INSERT */
726 # define argz_next rpl_argz_next
728 static char *argz_next LT_PARAMS((char *argz, size_t argz_len,
732 argz_next (argz, argz_len, entry)
737 assert ((argz && argz_len) || (!argz && !argz_len));
741 /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
742 within the ARGZ vector. */
743 assert ((!argz && !argz_len)
744 || ((argz <= entry) && (entry < (argz + argz_len))));
746 /* Move to the char immediately after the terminating
748 entry = 1+ strchr (entry, LT_EOS_CHAR);
750 /* Return either the new ENTRY, or else NULL if ARGZ is
752 return (entry >= argz + argz_len) ? 0 : (char *) entry;
756 /* This should probably be flagged as a programmer error,
757 since starting an argz_next loop with the iterator set
758 to ARGZ is safer. To preserve semantics, handle the NULL
759 case by returning the start of ARGZ (if any). */
766 #endif /* !HAVE_ARGZ_NEXT */
770 #if ! HAVE_ARGZ_STRINGIFY
771 # define argz_stringify rpl_argz_stringify
773 static void argz_stringify LT_PARAMS((char *argz, size_t argz_len,
777 argz_stringify (argz, argz_len, sep)
782 assert ((argz && argz_len) || (!argz && !argz_len));
786 --argz_len; /* don't stringify the terminating EOS */
787 while (--argz_len > 0)
789 if (argz[argz_len] == LT_EOS_CHAR)
790 argz[argz_len] = sep;
794 #endif /* !HAVE_ARGZ_STRINGIFY */
799 /* --- TYPE DEFINITIONS -- */
802 /* This type is used for the array of caller data sets in each handler. */
811 /* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
814 /* Extract the diagnostic strings from the error table macro in the same
815 order as the enumerated indices in ltdl.h. */
817 static const char *lt_dlerror_strings[] =
819 #define LT_ERROR(name, diagnostic) (diagnostic),
826 /* This structure is used for the list of registered loaders. */
828 struct lt_dlloader *next;
829 const char *loader_name; /* identifying name for each loader */
830 const char *sym_prefix; /* prefix for symbols */
831 lt_module_open *module_open;
832 lt_module_close *module_close;
833 lt_find_sym *find_sym;
834 lt_dlloader_exit *dlloader_exit;
835 lt_user_data dlloader_data;
838 struct lt_dlhandle_struct {
839 struct lt_dlhandle_struct *next;
840 lt_dlloader *loader; /* dlopening interface */
842 int depcount; /* number of dependencies */
843 lt_dlhandle *deplibs; /* dependencies */
844 lt_module module; /* system module handle */
845 lt_ptr system; /* system specific data */
846 lt_caller_data *caller_data; /* per caller associated data */
847 int flags; /* various boolean stats */
850 /* Various boolean flags can be stored in the flags field of an
851 lt_dlhandle_struct... */
852 #define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
853 #define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
855 #define LT_DLRESIDENT_FLAG (0x01 << 0)
856 /* ...add more flags here... */
858 #define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
861 #define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
863 static const char objdir[] = LTDL_OBJDIR;
864 static const char archive_ext[] = LTDL_ARCHIVE_EXT;
865 #ifdef LTDL_SHLIB_EXT
866 static const char shlib_ext[] = LTDL_SHLIB_EXT;
868 #ifdef LTDL_SYSSEARCHPATH
869 static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
875 /* --- MUTEX LOCKING --- */
878 /* Macros to make it easier to run the lock functions only if they have
879 been registered. The reason for the complicated lock macro is to
880 ensure that the stored error message from the last error is not
881 accidentally erased if the current function doesn't generate an
883 #define LT_DLMUTEX_LOCK() LT_STMT_START { \
884 if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \
886 #define LT_DLMUTEX_UNLOCK() LT_STMT_START { \
887 if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
889 #define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \
890 if (lt_dlmutex_seterror_func) \
891 (*lt_dlmutex_seterror_func) (errormsg); \
892 else lt_dllast_error = (errormsg); } LT_STMT_END
893 #define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \
894 if (lt_dlmutex_seterror_func) \
895 (errormsg) = (*lt_dlmutex_geterror_func) (); \
896 else (errormsg) = lt_dllast_error; } LT_STMT_END
898 /* The mutex functions stored here are global, and are necessarily the
899 same for all threads that wish to share access to libltdl. */
900 static lt_dlmutex_lock *lt_dlmutex_lock_func = 0;
901 static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0;
902 static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0;
903 static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0;
904 static const char *lt_dllast_error = 0;
907 /* Either set or reset the mutex functions. Either all the arguments must
908 be valid functions, or else all can be NULL to turn off locking entirely.
909 The registered functions should be manipulating a static global lock
910 from the lock() and unlock() callbacks, which needs to be reentrant. */
912 lt_dlmutex_register (lock, unlock, seterror, geterror)
913 lt_dlmutex_lock *lock;
914 lt_dlmutex_unlock *unlock;
915 lt_dlmutex_seterror *seterror;
916 lt_dlmutex_geterror *geterror;
918 lt_dlmutex_unlock *old_unlock = unlock;
921 /* Lock using the old lock() callback, if any. */
924 if ((lock && unlock && seterror && geterror)
925 || !(lock || unlock || seterror || geterror))
927 lt_dlmutex_lock_func = lock;
928 lt_dlmutex_unlock_func = unlock;
929 lt_dlmutex_geterror_func = geterror;
933 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
937 /* Use the old unlock() callback we saved earlier, if any. Otherwise
938 record any errors using internal storage. */
942 /* Return the number of errors encountered during the execution of
950 /* --- ERROR HANDLING --- */
953 static const char **user_error_strings = 0;
954 static int errorcount = LT_ERROR_MAX;
957 lt_dladderror (diagnostic)
958 const char *diagnostic;
962 const char **temp = (const char **) 0;
968 errindex = errorcount - LT_ERROR_MAX;
969 temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex);
972 user_error_strings = temp;
973 user_error_strings[errindex] = diagnostic;
974 result = errorcount++;
977 LT_DLMUTEX_UNLOCK ();
983 lt_dlseterror (errindex)
990 if (errindex >= errorcount || errindex < 0)
992 /* Ack! Error setting the error message! */
993 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
996 else if (errindex < LT_ERROR_MAX)
998 /* No error setting the error message! */
999 LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]);
1003 /* No error setting the error message! */
1004 LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]);
1007 LT_DLMUTEX_UNLOCK ();
1016 lt_ptr mem = lt_dlmalloc (size);
1018 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1023 lt_erealloc (addr, size)
1027 lt_ptr mem = lt_dlrealloc (addr, size);
1029 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1037 char *copy = strdup (str);
1038 if (LT_STRLEN (str) && !copy)
1039 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
1046 /* --- DLOPEN() INTERFACE LOADER --- */
1051 /* dynamic linking with dlopen/dlsym */
1058 # include <sys/dl.h>
1062 # define LT_GLOBAL RTLD_GLOBAL
1065 # define LT_GLOBAL DL_GLOBAL
1067 #endif /* !RTLD_GLOBAL */
1069 # define LT_GLOBAL 0
1070 #endif /* !LT_GLOBAL */
1072 /* We may have to define LT_LAZY_OR_NOW in the command line if we
1073 find out it does not work in some platform. */
1074 #ifndef LT_LAZY_OR_NOW
1076 # define LT_LAZY_OR_NOW RTLD_LAZY
1079 # define LT_LAZY_OR_NOW DL_LAZY
1081 # endif /* !RTLD_LAZY */
1083 #ifndef LT_LAZY_OR_NOW
1085 # define LT_LAZY_OR_NOW RTLD_NOW
1088 # define LT_LAZY_OR_NOW DL_NOW
1090 # endif /* !RTLD_NOW */
1092 #ifndef LT_LAZY_OR_NOW
1093 # define LT_LAZY_OR_NOW 0
1094 #endif /* !LT_LAZY_OR_NOW */
1097 # define DLERROR(arg) dlerror ()
1099 # define DLERROR(arg) LT_DLSTRERROR (arg)
1103 sys_dl_open (loader_data, filename)
1104 lt_user_data loader_data;
1105 const char *filename;
1107 lt_module module = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW);
1111 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN));
1118 sys_dl_close (loader_data, module)
1119 lt_user_data loader_data;
1124 if (dlclose (module) != 0)
1126 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
1134 sys_dl_sym (loader_data, module, symbol)
1135 lt_user_data loader_data;
1139 lt_ptr address = dlsym (module, symbol);
1143 LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
1149 static struct lt_user_dlloader sys_dl =
1156 sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
1159 #endif /* HAVE_LIBDL */
1163 /* --- SHL_LOAD() INTERFACE LOADER --- */
1167 /* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
1173 /* some flags are missing on some systems, so we provide
1174 * harmless defaults.
1177 * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
1178 * BIND_DEFERRED - Delay code symbol resolution until actual reference.
1181 * BIND_FIRST - Place the library at the head of the symbol search
1183 * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all
1184 * unsatisfied symbols as fatal. This flag allows
1185 * binding of unsatisfied code symbols to be deferred
1187 * [Perl: For certain libraries, like DCE, deferred
1188 * binding often causes run time problems. Adding
1189 * BIND_NONFATAL to BIND_IMMEDIATE still allows
1190 * unresolved references in situations like this.]
1191 * BIND_NOSTART - Do not call the initializer for the shared library
1192 * when the library is loaded, nor on a future call to
1194 * BIND_VERBOSE - Print verbose messages concerning possible
1195 * unsatisfied symbols.
1197 * hp9000s700/hp9000s800:
1198 * BIND_RESTRICTED - Restrict symbols visible by the library to those
1199 * present at library load time.
1200 * DYNAMIC_PATH - Allow the loader to dynamically search for the
1201 * library specified by the path argument.
1204 #ifndef DYNAMIC_PATH
1205 # define DYNAMIC_PATH 0
1207 #ifndef BIND_RESTRICTED
1208 # define BIND_RESTRICTED 0
1211 #define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
1214 sys_shl_open (loader_data, filename)
1215 lt_user_data loader_data;
1216 const char *filename;
1218 static shl_t self = (shl_t) 0;
1219 lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
1221 /* Since searching for a symbol against a NULL module handle will also
1222 look in everything else that was already loaded and exported with
1223 the -E compiler flag, we always cache a handle saved before any
1224 modules are loaded. */
1228 shl_findsym (&self, "main", TYPE_UNDEFINED, &address);
1237 module = shl_load (filename, LT_BIND_FLAGS, 0L);
1241 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1249 sys_shl_close (loader_data, module)
1250 lt_user_data loader_data;
1255 if (module && (shl_unload ((shl_t) (module)) != 0))
1257 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1265 sys_shl_sym (loader_data, module, symbol)
1266 lt_user_data loader_data;
1272 /* sys_shl_open should never return a NULL module handle */
1273 if (module == (lt_module) 0)
1275 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
1277 else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))
1281 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1288 static struct lt_user_dlloader sys_shl = {
1289 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
1292 #endif /* HAVE_SHL_LOAD */
1297 /* --- LOADLIBRARY() INTERFACE LOADER --- */
1301 /* dynamic linking for Win32 */
1303 #include <windows.h>
1305 /* Forward declaration; required to implement handle search below. */
1306 static lt_dlhandle handles;
1309 sys_wll_open (loader_data, filename)
1310 lt_user_data loader_data;
1311 const char *filename;
1314 lt_module module = 0;
1315 const char *errormsg = 0;
1316 char *searchname = 0;
1318 char self_name_buf[MAX_PATH];
1322 /* Get the name of main module */
1324 GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf));
1325 filename = ext = self_name_buf;
1329 ext = strrchr (filename, '.');
1334 /* FILENAME already has an extension. */
1335 searchname = lt_estrdup (filename);
1339 /* Append a `.' to stop Windows from adding an
1340 implicit `.dll' extension. */
1341 searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename));
1343 sprintf (searchname, "%s.", filename);
1350 char wpath[MAX_PATH];
1351 cygwin_conv_to_full_win32_path(searchname, wpath);
1352 module = LoadLibrary(wpath);
1355 module = LoadLibrary (searchname);
1357 LT_DLFREE (searchname);
1359 /* libltdl expects this function to fail if it is unable
1360 to physically load the library. Sadly, LoadLibrary
1361 will search the loaded libraries for a match and return
1362 one of them if the path search load fails.
1364 We check whether LoadLibrary is returning a handle to
1365 an already loaded module, and simulate failure if we
1377 if (cur->module == module)
1384 LT_DLMUTEX_UNLOCK ();
1388 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1396 sys_wll_close (loader_data, module)
1397 lt_user_data loader_data;
1402 if (FreeLibrary(module) == 0)
1404 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1412 sys_wll_sym (loader_data, module, symbol)
1413 lt_user_data loader_data;
1417 lt_ptr address = GetProcAddress (module, symbol);
1421 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1427 static struct lt_user_dlloader sys_wll = {
1428 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
1431 #endif /* __WINDOWS__ */
1436 /* --- LOAD_ADD_ON() INTERFACE LOADER --- */
1441 /* dynamic linking for BeOS */
1443 #include <kernel/image.h>
1446 sys_bedl_open (loader_data, filename)
1447 lt_user_data loader_data;
1448 const char *filename;
1454 image = load_add_on (filename);
1460 if (get_next_image_info (0, &cookie, &info) == B_OK)
1461 image = load_add_on (info.name);
1466 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1470 return (lt_module) image;
1474 sys_bedl_close (loader_data, module)
1475 lt_user_data loader_data;
1480 if (unload_add_on ((image_id) module) != B_OK)
1482 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1490 sys_bedl_sym (loader_data, module, symbol)
1491 lt_user_data loader_data;
1496 image_id image = (image_id) module;
1498 if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
1500 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1507 static struct lt_user_dlloader sys_bedl = {
1508 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
1511 #endif /* __BEOS__ */
1516 /* --- DLD_LINK() INTERFACE LOADER --- */
1521 /* dynamic linking with dld */
1528 sys_dld_open (loader_data, filename)
1529 lt_user_data loader_data;
1530 const char *filename;
1532 lt_module module = strdup (filename);
1534 if (dld_link (filename) != 0)
1536 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1545 sys_dld_close (loader_data, module)
1546 lt_user_data loader_data;
1551 if (dld_unlink_by_file ((char*)(module), 1) != 0)
1553 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1565 sys_dld_sym (loader_data, module, symbol)
1566 lt_user_data loader_data;
1570 lt_ptr address = dld_get_func (symbol);
1574 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1580 static struct lt_user_dlloader sys_dld = {
1581 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
1584 #endif /* HAVE_DLD */
1586 /* --- DYLD() MACOSX/DARWIN INTERFACE LOADER --- */
1590 #if HAVE_MACH_O_DYLD_H
1591 #if !defined(__APPLE_CC__) && !defined(__MWERKS__) && !defined(__private_extern__)
1592 /* Is this correct? Does it still function properly? */
1593 #define __private_extern__ extern
1595 # include <mach-o/dyld.h>
1597 #include <mach-o/getsect.h>
1599 /* We have to put some stuff here that isn't in older dyld.h files */
1600 #ifndef ENUM_DYLD_BOOL
1601 # define ENUM_DYLD_BOOL
1610 # define LC_REQ_DYLD 0x80000000
1612 #ifndef LC_LOAD_WEAK_DYLIB
1613 # define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
1615 static const struct mach_header * (*ltdl_NSAddImage)(const char *image_name, unsigned long options) = 0;
1616 static NSSymbol (*ltdl_NSLookupSymbolInImage)(const struct mach_header *image,const char *symbolName, unsigned long options) = 0;
1617 static enum DYLD_BOOL (*ltdl_NSIsSymbolNameDefinedInImage)(const struct mach_header *image, const char *symbolName) = 0;
1618 static enum DYLD_BOOL (*ltdl_NSMakePrivateModulePublic)(NSModule module) = 0;
1620 #ifndef NSADDIMAGE_OPTION_NONE
1621 #define NSADDIMAGE_OPTION_NONE 0x0
1623 #ifndef NSADDIMAGE_OPTION_RETURN_ON_ERROR
1624 #define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
1626 #ifndef NSADDIMAGE_OPTION_WITH_SEARCHING
1627 #define NSADDIMAGE_OPTION_WITH_SEARCHING 0x2
1629 #ifndef NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
1630 #define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
1632 #ifndef NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
1633 #define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
1635 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
1636 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
1638 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1639 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 0x1
1641 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
1642 #define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 0x2
1644 #ifndef NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1645 #define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
1650 lt_int_dyld_error(othererror)
1653 /* return the dyld error string, or the passed in error string if none */
1654 NSLinkEditErrors ler;
1658 NSLinkEditError(&ler,&lerno,&file,&errstr);
1659 if (!errstr || !strlen(errstr)) errstr = othererror;
1663 static const struct mach_header *
1664 lt_int_dyld_get_mach_header_from_nsmodule(module)
1667 /* There should probably be an apple dyld api for this */
1668 int i=_dyld_image_count();
1670 const char *modname=NSNameOfModule(module);
1671 const struct mach_header *mh=NULL;
1672 if (!modname) return NULL;
1673 for (j = 0; j < i; j++)
1675 if (!strcmp(_dyld_get_image_name(j),modname))
1677 mh=_dyld_get_image_header(j);
1684 static const char* lt_int_dyld_lib_install_name(mh)
1685 const struct mach_header *mh;
1687 /* NSAddImage is also used to get the loaded image, but it only works if the lib
1688 is installed, for uninstalled libs we need to check the install_names against
1689 each other. Note that this is still broken if DYLD_IMAGE_SUFFIX is set and a
1690 different lib was loaded as a result
1693 struct load_command *lc;
1694 unsigned long offset = sizeof(struct mach_header);
1695 const char* retStr=NULL;
1696 for (j = 0; j < mh->ncmds; j++)
1698 lc = (struct load_command*)(((unsigned long)mh) + offset);
1699 if (LC_ID_DYLIB == lc->cmd)
1701 retStr=(char*)(((struct dylib_command*)lc)->dylib.name.offset +
1704 offset += lc->cmdsize;
1709 static const struct mach_header *
1710 lt_int_dyld_match_loaded_lib_by_install_name(const char *name)
1712 int i=_dyld_image_count();
1714 const struct mach_header *mh=NULL;
1715 const char *id=NULL;
1716 for (j = 0; j < i; j++)
1718 id=lt_int_dyld_lib_install_name(_dyld_get_image_header(j));
1719 if ((id) && (!strcmp(id,name)))
1721 mh=_dyld_get_image_header(j);
1729 lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh)
1731 const struct mach_header *mh;
1733 /* Safe to assume our mh is good */
1735 struct load_command *lc;
1736 unsigned long offset = sizeof(struct mach_header);
1737 NSSymbol retSym = 0;
1738 const struct mach_header *mh1;
1739 if ((ltdl_NSLookupSymbolInImage) && NSIsSymbolNameDefined(symbol) )
1741 for (j = 0; j < mh->ncmds; j++)
1743 lc = (struct load_command*)(((unsigned long)mh) + offset);
1744 if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
1746 mh1=lt_int_dyld_match_loaded_lib_by_install_name((char*)(((struct dylib_command*)lc)->dylib.name.offset +
1747 (unsigned long)lc));
1750 /* Maybe NSAddImage can find it */
1751 mh1=ltdl_NSAddImage((char*)(((struct dylib_command*)lc)->dylib.name.offset +
1753 NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED +
1754 NSADDIMAGE_OPTION_WITH_SEARCHING +
1755 NSADDIMAGE_OPTION_RETURN_ON_ERROR );
1759 retSym = ltdl_NSLookupSymbolInImage(mh1,
1761 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1762 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1767 offset += lc->cmdsize;
1778 if (!_dyld_present()) {
1782 err = _dyld_func_lookup("__dyld_NSAddImage",(unsigned long*)<dl_NSAddImage);
1783 err = _dyld_func_lookup("__dyld_NSLookupSymbolInImage",(unsigned long*)<dl_NSLookupSymbolInImage);
1784 err = _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",(unsigned long*)<dl_NSIsSymbolNameDefinedInImage);
1785 err = _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",(unsigned long*)<dl_NSMakePrivateModulePublic);
1791 sys_dyld_open (loader_data, filename)
1792 lt_user_data loader_data;
1793 const char *filename;
1795 lt_module module = 0;
1796 NSObjectFileImage ofi = 0;
1797 NSObjectFileImageReturnCode ofirc;
1800 return (lt_module)-1;
1801 ofirc = NSCreateObjectFileImageFromFile(filename, &ofi);
1804 case NSObjectFileImageSuccess:
1805 module = NSLinkModule(ofi, filename,
1806 NSLINKMODULE_OPTION_RETURN_ON_ERROR
1807 | NSLINKMODULE_OPTION_PRIVATE
1808 | NSLINKMODULE_OPTION_BINDNOW);
1809 NSDestroyObjectFileImage(ofi);
1811 ltdl_NSMakePrivateModulePublic(module);
1813 case NSObjectFileImageInappropriateFile:
1814 if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
1816 module = (lt_module)ltdl_NSAddImage(filename, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
1820 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN)));
1823 if (!module) LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_OPEN)));
1828 sys_dyld_close (loader_data, module)
1829 lt_user_data loader_data;
1834 if (module == (lt_module)-1) return 0;
1835 #ifdef __BIG_ENDIAN__
1836 if (((struct mach_header *)module)->magic == MH_MAGIC)
1838 if (((struct mach_header *)module)->magic == MH_CIGAM)
1841 LT_DLMUTEX_SETERROR("Can not close a dylib");
1847 /* Currently, if a module contains c++ static destructors and it is unloaded, we
1848 get a segfault in atexit(), due to compiler and dynamic loader differences of
1849 opinion, this works around that.
1851 if ((const struct section *)NULL !=
1852 getsectbynamefromheader(lt_int_dyld_get_mach_header_from_nsmodule(module),
1853 "__DATA","__mod_term_func"))
1855 flags += NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
1859 flags += NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
1861 if (!NSUnLinkModule(module,flags))
1864 LT_DLMUTEX_SETERROR (lt_int_dyld_error(LT_DLSTRERROR(CANNOT_CLOSE)));
1872 sys_dyld_sym (loader_data, module, symbol)
1873 lt_user_data loader_data;
1878 NSSymbol *nssym = 0;
1880 const struct mach_header *mh=NULL;
1881 char saveError[256] = "Symbol not found";
1882 if (module == (lt_module)-1)
1884 _dyld_lookup_and_bind(symbol,(unsigned long*)&address,&unused);
1887 #ifdef __BIG_ENDIAN__
1888 if (((struct mach_header *)module)->magic == MH_MAGIC)
1890 if (((struct mach_header *)module)->magic == MH_CIGAM)
1893 if (ltdl_NSIsSymbolNameDefinedInImage && ltdl_NSLookupSymbolInImage)
1896 if (ltdl_NSIsSymbolNameDefinedInImage((struct mach_header*)module,symbol))
1898 nssym = ltdl_NSLookupSymbolInImage((struct mach_header*)module,
1900 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
1901 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
1908 nssym = NSLookupSymbolInModule(module, symbol);
1912 strncpy(saveError, lt_int_dyld_error(LT_DLSTRERROR(SYMBOL_NOT_FOUND)), 255);
1914 if (!mh) mh=lt_int_dyld_get_mach_header_from_nsmodule(module);
1915 nssym = lt_int_dyld_NSlookupSymbolInLinkedLibs(symbol,mh);
1919 LT_DLMUTEX_SETERROR (saveError);
1922 return NSAddressOfSymbol(nssym);
1925 static struct lt_user_dlloader sys_dyld =
1926 { "_", sys_dyld_open, sys_dyld_close, sys_dyld_sym, 0, 0 };
1929 #endif /* HAVE_DYLD */
1932 /* --- DLPREOPEN() INTERFACE LOADER --- */
1935 /* emulate dynamic linking using preloaded_symbols */
1937 typedef struct lt_dlsymlists_t
1939 struct lt_dlsymlists_t *next;
1940 const lt_dlsymlist *syms;
1943 static const lt_dlsymlist *default_preloaded_symbols = 0;
1944 static lt_dlsymlists_t *preloaded_symbols = 0;
1947 presym_init (loader_data)
1948 lt_user_data loader_data;
1954 preloaded_symbols = 0;
1955 if (default_preloaded_symbols)
1957 errors = lt_dlpreload (default_preloaded_symbols);
1960 LT_DLMUTEX_UNLOCK ();
1966 presym_free_symlists ()
1968 lt_dlsymlists_t *lists;
1972 lists = preloaded_symbols;
1975 lt_dlsymlists_t *tmp = lists;
1977 lists = lists->next;
1980 preloaded_symbols = 0;
1982 LT_DLMUTEX_UNLOCK ();
1988 presym_exit (loader_data)
1989 lt_user_data loader_data;
1991 presym_free_symlists ();
1996 presym_add_symlist (preloaded)
1997 const lt_dlsymlist *preloaded;
1999 lt_dlsymlists_t *tmp;
2000 lt_dlsymlists_t *lists;
2005 lists = preloaded_symbols;
2008 if (lists->syms == preloaded)
2012 lists = lists->next;
2015 tmp = LT_EMALLOC (lt_dlsymlists_t, 1);
2018 memset (tmp, 0, sizeof(lt_dlsymlists_t));
2019 tmp->syms = preloaded;
2020 tmp->next = preloaded_symbols;
2021 preloaded_symbols = tmp;
2029 LT_DLMUTEX_UNLOCK ();
2034 presym_open (loader_data, filename)
2035 lt_user_data loader_data;
2036 const char *filename;
2038 lt_dlsymlists_t *lists;
2039 lt_module module = (lt_module) 0;
2042 lists = preloaded_symbols;
2046 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
2050 /* Can't use NULL as the reflective symbol header, as NULL is
2051 used to mark the end of the entire symbol list. Self-dlpreopened
2052 symbols follow this magic number, chosen to be an unlikely
2053 clash with a real module name. */
2056 filename = "@PROGRAM@";
2061 const lt_dlsymlist *syms = lists->syms;
2065 if (!syms->address && strcmp(syms->name, filename) == 0)
2067 module = (lt_module) syms;
2073 lists = lists->next;
2076 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2079 LT_DLMUTEX_UNLOCK ();
2084 presym_close (loader_data, module)
2085 lt_user_data loader_data;
2088 /* Just to silence gcc -Wall */
2094 presym_sym (loader_data, module, symbol)
2095 lt_user_data loader_data;
2099 lt_dlsymlist *syms = (lt_dlsymlist*) module;
2102 while (syms->address)
2104 if (strcmp(syms->name, symbol) == 0)
2106 return syms->address;
2112 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
2117 static struct lt_user_dlloader presym = {
2118 0, presym_open, presym_close, presym_sym, presym_exit, 0
2125 /* --- DYNAMIC MODULE LOADING --- */
2128 /* The type of a function used at each iteration of foreach_dirinpath(). */
2129 typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1,
2132 static int foreach_dirinpath LT_PARAMS((const char *search_path,
2133 const char *base_name,
2134 foreach_callback_func *func,
2135 lt_ptr data1, lt_ptr data2));
2137 static int find_file_callback LT_PARAMS((char *filename, lt_ptr data,
2139 static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data,
2141 static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1,
2145 static int canonicalize_path LT_PARAMS((const char *path,
2146 char **pcanonical));
2147 static int argzize_path LT_PARAMS((const char *path,
2149 size_t *pargz_len));
2150 static FILE *find_file LT_PARAMS((const char *search_path,
2151 const char *base_name,
2153 static lt_dlhandle *find_handle LT_PARAMS((const char *search_path,
2154 const char *base_name,
2155 lt_dlhandle *handle));
2156 static int find_module LT_PARAMS((lt_dlhandle *handle,
2160 const char *old_name,
2162 static int free_vars LT_PARAMS((char *dlname, char *oldname,
2163 char *libdir, char *deplibs));
2164 static int load_deplibs LT_PARAMS((lt_dlhandle handle,
2166 static int trim LT_PARAMS((char **dest,
2168 static int try_dlopen LT_PARAMS((lt_dlhandle *handle,
2169 const char *filename));
2170 static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle,
2171 const char *filename));
2172 static int unload_deplibs LT_PARAMS((lt_dlhandle handle));
2173 static int lt_argz_insert LT_PARAMS((char **pargz,
2176 const char *entry));
2177 static int lt_argz_insertinorder LT_PARAMS((char **pargz,
2179 const char *entry));
2180 static int lt_argz_insertdir LT_PARAMS((char **pargz,
2183 struct dirent *dp));
2184 static int lt_dlpath_insertdir LT_PARAMS((char **ppath,
2187 static int list_files_by_dir LT_PARAMS((const char *dirnam,
2189 size_t *pargz_len));
2190 static int file_not_found LT_PARAMS((void));
2192 static char *user_search_path= 0;
2193 static lt_dlloader *loaders = 0;
2194 static lt_dlhandle handles = 0;
2195 static int initialized = 0;
2197 /* Initialize libltdl. */
2205 /* Initialize only at first call. */
2206 if (++initialized == 1)
2209 user_search_path = 0; /* empty search path */
2212 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
2215 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
2218 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
2221 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
2224 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
2227 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dyld, "dyld");
2228 errors += sys_dyld_init();
2230 errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
2232 if (presym_init (presym.dlloader_data))
2234 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
2237 else if (errors != 0)
2239 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
2244 LT_DLMUTEX_UNLOCK ();
2250 lt_dlpreload (preloaded)
2251 const lt_dlsymlist *preloaded;
2257 errors = presym_add_symlist (preloaded);
2261 presym_free_symlists();
2264 if (default_preloaded_symbols)
2266 errors = lt_dlpreload (default_preloaded_symbols);
2268 LT_DLMUTEX_UNLOCK ();
2275 lt_dlpreload_default (preloaded)
2276 const lt_dlsymlist *preloaded;
2279 default_preloaded_symbols = preloaded;
2280 LT_DLMUTEX_UNLOCK ();
2287 /* shut down libltdl */
2288 lt_dlloader *loader;
2296 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
2301 /* shut down only at last call. */
2302 if (--initialized == 0)
2306 while (handles && LT_DLIS_RESIDENT (handles))
2308 handles = handles->next;
2311 /* close all modules */
2312 for (level = 1; handles; ++level)
2314 lt_dlhandle cur = handles;
2315 int saw_nonresident = 0;
2319 lt_dlhandle tmp = cur;
2321 if (!LT_DLIS_RESIDENT (tmp))
2322 saw_nonresident = 1;
2323 if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
2325 if (lt_dlclose (tmp))
2331 /* done if only resident modules are left */
2332 if (!saw_nonresident)
2336 /* close all loaders */
2339 lt_dlloader *next = loader->next;
2340 lt_user_data data = loader->dlloader_data;
2341 if (loader->dlloader_exit && loader->dlloader_exit (data))
2346 LT_DLMEM_REASSIGN (loader, next);
2352 LT_DLMUTEX_UNLOCK ();
2357 tryall_dlopen (handle, filename)
2358 lt_dlhandle *handle;
2359 const char *filename;
2362 lt_dlloader *loader;
2363 const char *saved_error;
2366 LT_DLMUTEX_GETERROR (saved_error);
2372 /* check whether the module was already opened */
2375 /* try to dlopen the program itself? */
2376 if (!cur->info.filename && !filename)
2381 if (cur->info.filename && filename
2382 && strcmp (cur->info.filename, filename) == 0)
2392 ++cur->info.ref_count;
2400 /* Comment out the check of file permissions using access.
2401 This call seems to always return -1 with error EACCES.
2403 /* We need to catch missing file errors early so that
2404 file_not_found() can detect what happened.
2405 if (access (filename, R_OK) != 0)
2407 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2412 cur->info.filename = lt_estrdup (filename);
2413 if (!cur->info.filename)
2421 cur->info.filename = 0;
2426 lt_user_data data = loader->dlloader_data;
2428 cur->module = loader->module_open (data, filename);
2430 if (cur->module != 0)
2434 loader = loader->next;
2439 LT_DLFREE (cur->info.filename);
2444 cur->loader = loader;
2445 LT_DLMUTEX_SETERROR (saved_error);
2448 LT_DLMUTEX_UNLOCK ();
2454 tryall_dlopen_module (handle, prefix, dirname, dlname)
2455 lt_dlhandle *handle;
2457 const char *dirname;
2462 size_t filename_len = 0;
2463 size_t dirname_len = LT_STRLEN (dirname);
2468 #ifdef LT_DIRSEP_CHAR
2469 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
2470 should make it into this function: */
2471 assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
2474 if (dirname_len > 0)
2475 if (dirname[dirname_len -1] == '/')
2477 filename_len = dirname_len + 1 + LT_STRLEN (dlname);
2479 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
2480 The PREFIX (if any) is handled below. */
2481 filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);
2485 sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
2487 /* Now that we have combined DIRNAME and MODULENAME, if there is
2488 also a PREFIX to contend with, simply recurse with the arguments
2489 shuffled. Otherwise, attempt to open FILENAME as a module. */
2492 error += tryall_dlopen_module (handle,
2493 (const char *) 0, prefix, filename);
2495 else if (tryall_dlopen (handle, filename) != 0)
2500 LT_DLFREE (filename);
2505 find_module (handle, dir, libdir, dlname, old_name, installed)
2506 lt_dlhandle *handle;
2510 const char *old_name;
2513 /* Try to open the old library first; if it was dlpreopened,
2514 we want the preopened version of it, even if a dlopenable
2515 module is available. */
2516 if (old_name && tryall_dlopen (handle, old_name) == 0)
2521 /* Try to open the dynamic library. */
2524 /* try to open the installed module */
2525 if (installed && libdir)
2527 if (tryall_dlopen_module (handle,
2528 (const char *) 0, libdir, dlname) == 0)
2532 /* try to open the not-installed module */
2535 if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
2539 /* maybe it was moved to another directory */
2541 if (tryall_dlopen_module (handle,
2542 (const char *) 0, dir, dlname) == 0)
2552 canonicalize_path (path, pcanonical)
2556 char *canonical = 0;
2558 assert (path && *path);
2559 assert (pcanonical);
2561 canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));
2568 for (src = 0; path[src] != LT_EOS_CHAR; ++src)
2570 /* Path separators are not copied to the beginning or end of
2571 the destination, or if another separator would follow
2573 if (path[src] == LT_PATHSEP_CHAR)
2576 || (path[1+ src] == LT_PATHSEP_CHAR)
2577 || (path[1+ src] == LT_EOS_CHAR))
2581 /* Anything other than a directory separator is copied verbatim. */
2582 if ((path[src] != '/')
2583 #ifdef LT_DIRSEP_CHAR
2584 && (path[src] != LT_DIRSEP_CHAR)
2588 canonical[dest++] = path[src];
2590 /* Directory separators are converted and copied only if they are
2591 not at the end of a path -- i.e. before a path separator or
2593 else if ((path[1+ src] != LT_PATHSEP_CHAR)
2594 && (path[1+ src] != LT_EOS_CHAR)
2595 #ifdef LT_DIRSEP_CHAR
2596 && (path[1+ src] != LT_DIRSEP_CHAR)
2598 && (path[1+ src] != '/'))
2600 canonical[dest++] = '/';
2604 /* Add an end-of-string marker at the end. */
2605 canonical[dest] = LT_EOS_CHAR;
2608 /* Assign new value. */
2609 *pcanonical = canonical;
2615 argzize_path (path, pargz, pargz_len)
2626 if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
2631 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2634 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
2644 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
2645 of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
2646 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
2647 it is appended to each SEARCH_PATH element before FUNC is called. */
2649 foreach_dirinpath (search_path, base_name, func, data1, data2)
2650 const char *search_path;
2651 const char *base_name;
2652 foreach_callback_func *func;
2657 int filenamesize = 0;
2658 size_t lenbase = LT_STRLEN (base_name);
2659 size_t argz_len = 0;
2662 char *canonical = 0;
2666 if (!search_path || !*search_path)
2668 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2672 if (canonicalize_path (search_path, &canonical) != 0)
2675 if (argzize_path (canonical, &argz, &argz_len) != 0)
2680 while ((dir_name = argz_next (argz, argz_len, dir_name)))
2682 size_t lendir = LT_STRLEN (dir_name);
2684 if (lendir +1 +lenbase >= filenamesize)
2686 LT_DLFREE (filename);
2687 filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */
2688 filename = LT_EMALLOC (char, filenamesize);
2693 assert (filenamesize > lendir);
2694 strcpy (filename, dir_name);
2696 if (base_name && *base_name)
2698 if (filename[lendir -1] != '/')
2699 filename[lendir++] = '/';
2700 strcpy (filename +lendir, base_name);
2703 if ((result = (*func) (filename, data1, data2)))
2712 LT_DLFREE (canonical);
2713 LT_DLFREE (filename);
2715 LT_DLMUTEX_UNLOCK ();
2720 /* If FILEPATH can be opened, store the name of the directory component
2721 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
2722 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
2724 find_file_callback (filename, data1, data2)
2729 char **pdir = (char **) data1;
2730 FILE **pfile = (FILE **) data2;
2733 assert (filename && *filename);
2737 if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
2739 char *dirend = strrchr (filename, '/');
2741 if (dirend > filename)
2742 *dirend = LT_EOS_CHAR;
2745 *pdir = lt_estrdup (filename);
2746 is_done = (*pdir == 0) ? -1 : 1;
2753 find_file (search_path, base_name, pdir)
2754 const char *search_path;
2755 const char *base_name;
2760 foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
2766 find_handle_callback (filename, data, ignored)
2771 lt_dlhandle *handle = (lt_dlhandle *) data;
2772 int notfound = access (filename, R_OK);
2774 /* Bail out if file cannot be read... */
2778 /* Try to dlopen the file, but do not continue searching in any
2780 if (tryall_dlopen (handle, filename) != 0)
2786 /* If HANDLE was found return it, otherwise return 0. If HANDLE was
2787 found but could not be opened, *HANDLE will be set to 0. */
2788 static lt_dlhandle *
2789 find_handle (search_path, base_name, handle)
2790 const char *search_path;
2791 const char *base_name;
2792 lt_dlhandle *handle;
2797 if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
2805 load_deplibs (handle, deplibs)
2809 #if LTDL_DLOPEN_DEPLIBS
2810 char *p, *save_search_path = 0;
2817 handle->depcount = 0;
2819 #if LTDL_DLOPEN_DEPLIBS
2827 if (user_search_path)
2829 save_search_path = lt_estrdup (user_search_path);
2830 if (!save_search_path)
2834 /* extract search paths and count deplibs */
2838 if (!isspace ((int) *p))
2841 while (*end && !isspace((int) *end))
2846 if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
2849 *end = 0; /* set a temporary string terminator */
2850 if (lt_dladdsearchdir(p+2))
2869 /* restore the old search path */
2870 LT_DLFREE (user_search_path);
2871 user_search_path = save_search_path;
2873 LT_DLMUTEX_UNLOCK ();
2881 names = LT_EMALLOC (char *, depcount * sizeof (char*));
2885 /* now only extract the actual deplibs */
2890 if (isspace ((int) *p))
2897 while (*end && !isspace ((int) *end))
2902 if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
2906 *end = 0; /* set a temporary string terminator */
2907 if (strncmp(p, "-l", 2) == 0)
2909 size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
2910 name = LT_EMALLOC (char, 1+ name_len);
2912 sprintf (name, "lib%s", p+2);
2915 name = lt_estrdup(p);
2920 names[depcount++] = name;
2927 /* load the deplibs (in reverse order)
2928 At this stage, don't worry if the deplibs do not load correctly,
2929 they may already be statically linked into the loading application
2930 for instance. There will be a more enlightening error message
2931 later on if the loaded module cannot resolve all of its symbols. */
2936 handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount);
2937 if (!handle->deplibs)
2940 for (i = 0; i < depcount; ++i)
2942 handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
2943 if (handle->deplibs[j])
2949 handle->depcount = j; /* Number of successfully loaded deplibs */
2954 for (i = 0; i < depcount; ++i)
2956 LT_DLFREE (names[i]);
2967 unload_deplibs (handle)
2973 if (handle->depcount)
2975 for (i = 0; i < handle->depcount; ++i)
2977 if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
2979 errors += lt_dlclose (handle->deplibs[i]);
2992 /* remove the leading and trailing "'" from str
2993 and store the result in dest */
2994 const char *end = strrchr (str, '\'');
2995 size_t len = LT_STRLEN (str);
3000 if (len > 3 && str[0] == '\'')
3002 tmp = LT_EMALLOC (char, end - str);
3006 strncpy(tmp, &str[1], (end - str) - 1);
3007 tmp[len-3] = LT_EOS_CHAR;
3019 free_vars (dlname, oldname, libdir, deplibs)
3026 LT_DLFREE (oldname);
3028 LT_DLFREE (deplibs);
3034 try_dlopen (phandle, filename)
3035 lt_dlhandle *phandle;
3036 const char *filename;
3038 const char * ext = 0;
3039 const char * saved_error = 0;
3040 char * canonical = 0;
3041 char * base_name = 0;
3045 lt_dlhandle newhandle;
3048 assert (*phandle == 0);
3050 LT_DLMUTEX_GETERROR (saved_error);
3055 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3059 memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3060 newhandle = *phandle;
3062 /* lt_dlclose()ing yourself is very bad! Disallow it. */
3063 LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
3065 if (tryall_dlopen (&newhandle, 0) != 0)
3067 LT_DLFREE (*phandle);
3071 goto register_handle;
3074 assert (filename && *filename);
3076 /* Doing this immediately allows internal functions to safely
3077 assume only canonicalized paths are passed. */
3078 if (canonicalize_path (filename, &canonical) != 0)
3084 /* If the canonical module name is a path (relative or absolute)
3085 then split it into a directory part and a name part. */
3086 base_name = strrchr (canonical, '/');
3089 size_t dirlen = (1+ base_name) - canonical;
3091 dir = LT_EMALLOC (char, 1+ dirlen);
3098 strncpy (dir, canonical, dirlen);
3099 dir[dirlen] = LT_EOS_CHAR;
3104 LT_DLMEM_REASSIGN (base_name, canonical);
3106 assert (base_name && *base_name);
3108 /* Check whether we are opening a libtool module (.la extension). */
3109 ext = strrchr (base_name, '.');
3110 if (ext && strcmp (ext, archive_ext) == 0)
3112 /* this seems to be a libtool module */
3115 char * old_name = 0;
3121 /* if we can't find the installed flag, it is probably an
3122 installed libtool archive, produced with an old version
3126 /* extract the module name from the file name */
3127 name = LT_EMALLOC (char, ext - base_name + 1);
3134 /* canonicalize the module name */
3137 for (i = 0; i < ext - base_name; ++i)
3139 if (isalnum ((int)(base_name[i])))
3141 name[i] = base_name[i];
3148 name[ext - base_name] = LT_EOS_CHAR;
3151 /* Now try to open the .la file. If there is no directory name
3152 component, try to find it first in user_search_path and then other
3153 prescribed paths. Otherwise (or in any case if the module was not
3154 yet found) try opening just the module name as passed. */
3157 const char *search_path;
3160 search_path = user_search_path;
3162 file = find_file (user_search_path, base_name, &dir);
3163 LT_DLMUTEX_UNLOCK ();
3167 search_path = getenv (LTDL_SEARCHPATH_VAR);
3169 file = find_file (search_path, base_name, &dir);
3172 #ifdef LTDL_SHLIBPATH_VAR
3175 search_path = getenv (LTDL_SHLIBPATH_VAR);
3177 file = find_file (search_path, base_name, &dir);
3180 #ifdef LTDL_SYSSEARCHPATH
3181 if (!file && sys_search_path)
3183 file = find_file (sys_search_path, base_name, &dir);
3189 file = fopen (filename, LT_READTEXT_MODE);
3192 /* If we didn't find the file by now, it really isn't there. Set
3193 the status flag, and bail out. */
3196 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3201 line_len = LT_FILENAME_MAX;
3202 line = LT_EMALLOC (char, line_len);
3210 /* read the .la file */
3211 while (!feof (file))
3213 if (!fgets (line, (int) line_len, file))
3218 /* Handle the case where we occasionally need to read a line
3219 that is longer than the initial buffer size. */
3220 while ((line[LT_STRLEN(line) -1] != '\n') && (!feof (file)))
3222 line = LT_DLREALLOC (char, line, line_len *2);
3223 if (!fgets (&line[line_len -1], (int) line_len +1, file))
3230 if (line[0] == '\n' || line[0] == '#')
3236 #define STR_DLNAME "dlname="
3237 if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
3239 errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
3242 #undef STR_OLD_LIBRARY
3243 #define STR_OLD_LIBRARY "old_library="
3244 else if (strncmp (line, STR_OLD_LIBRARY,
3245 sizeof (STR_OLD_LIBRARY) - 1) == 0)
3247 errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
3250 #define STR_LIBDIR "libdir="
3251 else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
3253 errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);
3256 #undef STR_DL_DEPLIBS
3257 #define STR_DL_DEPLIBS "dependency_libs="
3258 else if (strncmp (line, STR_DL_DEPLIBS,
3259 sizeof (STR_DL_DEPLIBS) - 1) == 0)
3261 errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
3263 else if (strcmp (line, "installed=yes\n") == 0)
3267 else if (strcmp (line, "installed=no\n") == 0)
3272 #undef STR_LIBRARY_NAMES
3273 #define STR_LIBRARY_NAMES "library_names="
3274 else if (! dlname && strncmp (line, STR_LIBRARY_NAMES,
3275 sizeof (STR_LIBRARY_NAMES) - 1) == 0)
3278 errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
3281 && (last_libname = strrchr (dlname, ' ')) != 0)
3283 last_libname = lt_estrdup (last_libname + 1);
3289 LT_DLMEM_REASSIGN (dlname, last_libname);
3300 /* allocate the handle */
3301 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3307 free_vars (dlname, old_name, libdir, deplibs);
3308 LT_DLFREE (*phandle);
3314 memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
3315 if (load_deplibs (*phandle, deplibs) == 0)
3317 newhandle = *phandle;
3318 /* find_module may replace newhandle */
3319 if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
3321 unload_deplibs (*phandle);
3330 free_vars (dlname, old_name, libdir, deplibs);
3333 LT_DLFREE (*phandle);
3337 if (*phandle != newhandle)
3339 unload_deplibs (*phandle);
3344 /* not a libtool module */
3345 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
3352 memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
3353 newhandle = *phandle;
3355 /* If the module has no directory name component, try to find it
3356 first in user_search_path and then other prescribed paths.
3357 Otherwise (or in any case if the module was not yet found) try
3358 opening just the module name as passed. */
3359 if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
3360 && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
3362 #ifdef LTDL_SHLIBPATH_VAR
3363 && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
3366 #ifdef LTDL_SYSSEARCHPATH
3367 && !find_handle (sys_search_path, base_name, &newhandle)
3371 if (tryall_dlopen (&newhandle, filename) != 0)
3379 LT_DLFREE (*phandle);
3386 LT_DLMEM_REASSIGN (*phandle, newhandle);
3388 if ((*phandle)->info.ref_count == 0)
3390 (*phandle)->info.ref_count = 1;
3391 LT_DLMEM_REASSIGN ((*phandle)->info.name, name);
3394 (*phandle)->next = handles;
3396 LT_DLMUTEX_UNLOCK ();
3399 LT_DLMUTEX_SETERROR (saved_error);
3404 LT_DLFREE (canonical);
3410 lt_dlopen (filename)
3411 const char *filename;
3413 lt_dlhandle handle = 0;
3415 /* Just incase we missed a code path in try_dlopen() that reports
3416 an error, but forgets to reset handle... */
3417 if (try_dlopen (&handle, filename) != 0)
3423 /* If the last error messge store was `FILE_NOT_FOUND', then return
3428 const char *error = 0;
3430 LT_DLMUTEX_GETERROR (error);
3431 if (error == LT_DLSTRERROR (FILE_NOT_FOUND))
3437 /* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
3438 open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
3439 and if a file is still not found try again with SHLIB_EXT appended
3442 lt_dlopenext (filename)
3443 const char *filename;
3445 lt_dlhandle handle = 0;
3453 return lt_dlopen (filename);
3458 len = LT_STRLEN (filename);
3459 ext = strrchr (filename, '.');
3461 /* If FILENAME already bears a suitable extension, there is no need
3462 to try appending additional extensions. */
3463 if (ext && ((strcmp (ext, archive_ext) == 0)
3464 #ifdef LTDL_SHLIB_EXT
3465 || (strcmp (ext, shlib_ext) == 0)
3469 return lt_dlopen (filename);
3472 /* First try appending ARCHIVE_EXT. */
3473 tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1);
3477 strcpy (tmp, filename);
3478 strcat (tmp, archive_ext);
3479 errors = try_dlopen (&handle, tmp);
3481 /* If we found FILENAME, stop searching -- whether we were able to
3482 load the file as a module or not. If the file exists but loading
3483 failed, it is better to return an error message here than to
3484 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
3485 in the module search path. */
3486 if (handle || ((errors > 0) && !file_not_found ()))
3492 #ifdef LTDL_SHLIB_EXT
3493 /* Try appending SHLIB_EXT. */
3494 if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
3497 tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
3501 strcpy (tmp, filename);
3505 tmp[len] = LT_EOS_CHAR;
3508 strcat(tmp, shlib_ext);
3509 errors = try_dlopen (&handle, tmp);
3511 /* As before, if the file was found but loading failed, return now
3512 with the current error message. */
3513 if (handle || ((errors > 0) && !file_not_found ()))
3520 /* Still here? Then we really did fail to locate any of the file
3522 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3529 lt_argz_insert (pargz, pargz_len, before, entry)
3537 if ((error = argz_insert (pargz, pargz_len, before, entry)))
3542 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
3545 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
3555 lt_argz_insertinorder (pargz, pargz_len, entry)
3564 assert (entry && *entry);
3567 while ((before = argz_next (*pargz, *pargz_len, before)))
3569 int cmp = strcmp (entry, before);
3572 if (cmp == 0) return 0; /* No duplicates! */
3575 return lt_argz_insert (pargz, pargz_len, before, entry);
3579 lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
3588 size_t end_offset = 0;
3596 dir_len = LT_STRLEN (dirnam);
3597 end = dp->d_name + LT_D_NAMLEN(dp);
3599 /* Ignore version numbers. */
3602 for (p = end; p -1 > dp->d_name; --p)
3603 if (strchr (".0123456789", p[-1]) == 0)
3610 /* Ignore filename extension. */
3613 for (p = end -1; p > dp->d_name; --p)
3621 /* Prepend the directory name. */
3622 end_offset = end - dp->d_name;
3623 buf_len = dir_len + 1+ end_offset;
3624 buf = LT_EMALLOC (char, 1+ buf_len);
3630 strcpy (buf, dirnam);
3632 strncat (buf, dp->d_name, end_offset);
3633 buf[buf_len] = LT_EOS_CHAR;
3635 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
3636 if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
3645 list_files_by_dir (dirnam, pargz, pargz_len)
3653 assert (dirnam && *dirnam);
3656 assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
3658 dirp = opendir (dirnam);
3661 struct dirent *dp = 0;
3663 while ((dp = readdir (dirp)))
3664 if (dp->d_name[0] != '.')
3665 if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
3680 /* If there are any files in DIRNAME, call the function passed in
3681 DATA1 (with the name of each file and DATA2 as arguments). */
3683 foreachfile_callback (dirname, data1, data2)
3688 int (*func) LT_PARAMS((const char *filename, lt_ptr data))
3689 = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
3693 size_t argz_len = 0;
3695 if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
3702 while ((filename = argz_next (argz, argz_len, filename)))
3703 if ((is_done = (*func) (filename, data2)))
3714 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
3715 with DATA. The filenames passed to FUNC would be suitable for
3716 passing to lt_dlopenext. The extensions are stripped so that
3717 individual modules do not generate several entries (e.g. libfoo.la,
3718 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
3719 then the same directories that lt_dlopen would search are examined. */
3721 lt_dlforeachfile (search_path, func, data)
3722 const char *search_path;
3723 int (*func) LT_PARAMS ((const char *filename, lt_ptr data));
3730 /* If a specific path was passed, search only the directories
3732 is_done = foreach_dirinpath (search_path, 0,
3733 foreachfile_callback, func, data);
3737 /* Otherwise search the default paths. */
3738 is_done = foreach_dirinpath (user_search_path, 0,
3739 foreachfile_callback, func, data);
3742 is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
3743 foreachfile_callback, func, data);
3746 #ifdef LTDL_SHLIBPATH_VAR
3749 is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0,
3750 foreachfile_callback, func, data);
3753 #ifdef LTDL_SYSSEARCHPATH
3756 is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0,
3757 foreachfile_callback, func, data);
3769 lt_dlhandle cur, last;
3774 /* check whether the handle is valid */
3775 last = cur = handles;
3776 while (cur && handle != cur)
3784 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3789 handle->info.ref_count--;
3791 /* Note that even with resident modules, we must track the ref_count
3792 correctly incase the user decides to reset the residency flag
3793 later (even though the API makes no provision for that at the
3795 if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
3797 lt_user_data data = handle->loader->dlloader_data;
3799 if (handle != handles)
3801 last->next = handle->next;
3805 handles = handle->next;
3808 errors += handle->loader->module_close (data, handle->module);
3809 errors += unload_deplibs(handle);
3811 /* It is up to the callers to free the data itself. */
3812 LT_DLFREE (handle->caller_data);
3814 LT_DLFREE (handle->info.filename);
3815 LT_DLFREE (handle->info.name);
3821 if (LT_DLIS_RESIDENT (handle))
3823 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
3828 LT_DLMUTEX_UNLOCK ();
3834 lt_dlsym (handle, symbol)
3839 char lsym[LT_SYMBOL_LENGTH];
3846 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3852 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
3856 lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
3857 + LT_STRLEN (handle->info.name);
3859 if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
3865 sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
3868 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
3873 data = handle->loader->dlloader_data;
3874 if (handle->info.name)
3876 const char *saved_error;
3878 LT_DLMUTEX_GETERROR (saved_error);
3880 /* this is a libtool module */
3881 if (handle->loader->sym_prefix)
3883 strcpy(sym, handle->loader->sym_prefix);
3884 strcat(sym, handle->info.name);
3888 strcpy(sym, handle->info.name);
3891 strcat(sym, "_LTX_");
3892 strcat(sym, symbol);
3894 /* try "modulename_LTX_symbol" */
3895 address = handle->loader->find_sym (data, handle->module, sym);
3904 LT_DLMUTEX_SETERROR (saved_error);
3907 /* otherwise try "symbol" */
3908 if (handle->loader->sym_prefix)
3910 strcpy(sym, handle->loader->sym_prefix);
3911 strcat(sym, symbol);
3915 strcpy(sym, symbol);
3918 address = handle->loader->find_sym (data, handle->module, sym);
3932 LT_DLMUTEX_GETERROR (error);
3933 LT_DLMUTEX_SETERROR (0);
3935 return error ? error : NULL;
3939 lt_dlpath_insertdir (ppath, before, dir)
3945 char *canonical = 0;
3947 size_t argz_len = 0;
3950 assert (dir && *dir);
3952 if (canonicalize_path (dir, &canonical) != 0)
3958 assert (canonical && *canonical);
3960 /* If *PPATH is empty, set it to DIR. */
3963 assert (!before); /* BEFORE cannot be set without PPATH. */
3964 assert (dir); /* Without DIR, don't call this function! */
3966 *ppath = lt_estrdup (dir);
3973 assert (ppath && *ppath);
3975 if (argzize_path (*ppath, &argz, &argz_len) != 0)
3981 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
3982 if *PPATH is already canonicalized, and hence does not change length
3983 with respect to ARGZ. We canonicalize each entry as it is added to
3984 the search path, and don't call this function with (uncanonicalized)
3985 user paths, so this is a fair assumption. */
3988 assert (*ppath <= before);
3989 assert (before - *ppath <= strlen (*ppath));
3991 before = before - *ppath + argz;
3994 if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
4000 argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
4001 LT_DLMEM_REASSIGN (*ppath, argz);
4004 LT_DLFREE (canonical);
4011 lt_dladdsearchdir (search_dir)
4012 const char *search_dir;
4016 if (search_dir && *search_dir)
4019 if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
4021 LT_DLMUTEX_UNLOCK ();
4028 lt_dlinsertsearchdir (before, search_dir)
4030 const char *search_dir;
4037 if ((before < user_search_path)
4038 || (before >= user_search_path + LT_STRLEN (user_search_path)))
4040 LT_DLMUTEX_UNLOCK ();
4041 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
4044 LT_DLMUTEX_UNLOCK ();
4047 if (search_dir && *search_dir)
4050 if (lt_dlpath_insertdir (&user_search_path,
4051 (char *) before, search_dir) != 0)
4055 LT_DLMUTEX_UNLOCK ();
4062 lt_dlsetsearchpath (search_path)
4063 const char *search_path;
4068 LT_DLFREE (user_search_path);
4069 LT_DLMUTEX_UNLOCK ();
4071 if (!search_path || !LT_STRLEN (search_path))
4077 if (canonicalize_path (search_path, &user_search_path) != 0)
4079 LT_DLMUTEX_UNLOCK ();
4085 lt_dlgetsearchpath ()
4087 const char *saved_path;
4090 saved_path = user_search_path;
4091 LT_DLMUTEX_UNLOCK ();
4097 lt_dlmakeresident (handle)
4104 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4109 LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
4116 lt_dlisresident (handle)
4121 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4125 return LT_DLIS_RESIDENT (handle);
4131 /* --- MODULE INFORMATION --- */
4134 lt_dlgetinfo (handle)
4139 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4143 return &(handle->info);
4147 lt_dlhandle_next (place)
4150 return place ? place->next : handles;
4154 lt_dlforeach (func, data)
4155 int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data));
4166 lt_dlhandle tmp = cur;
4169 if ((*func) (tmp, data))
4176 LT_DLMUTEX_UNLOCK ();
4182 lt_dlcaller_register ()
4184 static lt_dlcaller_id last_caller_id = 0;
4188 result = ++last_caller_id;
4189 LT_DLMUTEX_UNLOCK ();
4195 lt_dlcaller_set_data (key, handle, data)
4201 lt_ptr stale = (lt_ptr) 0;
4204 /* This needs to be locked so that the caller data can be updated
4205 simultaneously by different threads. */
4208 if (handle->caller_data)
4209 while (handle->caller_data[n_elements].key)
4212 for (i = 0; i < n_elements; ++i)
4214 if (handle->caller_data[i].key == key)
4216 stale = handle->caller_data[i].data;
4221 /* Ensure that there is enough room in this handle's caller_data
4222 array to accept a new element (and an empty end marker). */
4223 if (i == n_elements)
4225 lt_caller_data *temp
4226 = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements);
4234 handle->caller_data = temp;
4236 /* We only need this if we needed to allocate a new caller_data. */
4237 handle->caller_data[i].key = key;
4238 handle->caller_data[1+ i].key = 0;
4241 handle->caller_data[i].data = data;
4244 LT_DLMUTEX_UNLOCK ();
4250 lt_dlcaller_get_data (key, handle)
4254 lt_ptr result = (lt_ptr) 0;
4256 /* This needs to be locked so that the caller data isn't updated by
4257 another thread part way through this function. */
4260 /* Locate the index of the element with a matching KEY. */
4263 for (i = 0; handle->caller_data[i].key; ++i)
4265 if (handle->caller_data[i].key == key)
4267 result = handle->caller_data[i].data;
4273 LT_DLMUTEX_UNLOCK ();
4280 /* --- USER MODULE LOADER API --- */
4284 lt_dlloader_add (place, dlloader, loader_name)
4286 const struct lt_user_dlloader *dlloader;
4287 const char *loader_name;
4290 lt_dlloader *node = 0, *ptr = 0;
4292 if ((dlloader == 0) /* diagnose null parameters */
4293 || (dlloader->module_open == 0)
4294 || (dlloader->module_close == 0)
4295 || (dlloader->find_sym == 0))
4297 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4301 /* Create a new dlloader node with copies of the user callbacks. */
4302 node = LT_EMALLOC (lt_dlloader, 1);
4307 node->loader_name = loader_name;
4308 node->sym_prefix = dlloader->sym_prefix;
4309 node->dlloader_exit = dlloader->dlloader_exit;
4310 node->module_open = dlloader->module_open;
4311 node->module_close = dlloader->module_close;
4312 node->find_sym = dlloader->find_sym;
4313 node->dlloader_data = dlloader->dlloader_data;
4318 /* If there are no loaders, NODE becomes the list! */
4323 /* If PLACE is not set, add NODE to the end of the
4325 for (ptr = loaders; ptr->next; ptr = ptr->next)
4332 else if (loaders == place)
4334 /* If PLACE is the first loader, NODE goes first. */
4340 /* Find the node immediately preceding PLACE. */
4341 for (ptr = loaders; ptr->next != place; ptr = ptr->next)
4346 if (ptr->next != place)
4348 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4353 /* Insert NODE between PTR and PLACE. */
4359 LT_DLMUTEX_UNLOCK ();
4365 lt_dlloader_remove (loader_name)
4366 const char *loader_name;
4368 lt_dlloader *place = lt_dlloader_find (loader_name);
4374 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4380 /* Fail if there are any open modules which use this loader. */
4381 for (handle = handles; handle; handle = handle->next)
4383 if (handle->loader == place)
4385 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
4391 if (place == loaders)
4393 /* PLACE is the first loader in the list. */
4394 loaders = loaders->next;
4398 /* Find the loader before the one being removed. */
4400 for (prev = loaders; prev->next; prev = prev->next)
4402 if (!strcmp (prev->next->loader_name, loader_name))
4409 prev->next = prev->next->next;
4412 if (place->dlloader_exit)
4414 errors = place->dlloader_exit (place->dlloader_data);
4420 LT_DLMUTEX_UNLOCK ();
4426 lt_dlloader_next (place)
4432 next = place ? place->next : loaders;
4433 LT_DLMUTEX_UNLOCK ();
4439 lt_dlloader_name (place)
4442 const char *name = 0;
4447 name = place ? place->loader_name : 0;
4448 LT_DLMUTEX_UNLOCK ();
4452 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4459 lt_dlloader_data (place)
4462 lt_user_data *data = 0;
4467 data = place ? &(place->dlloader_data) : 0;
4468 LT_DLMUTEX_UNLOCK ();
4472 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4479 lt_dlloader_find (loader_name)
4480 const char *loader_name;
4482 lt_dlloader *place = 0;
4485 for (place = loaders; place; place = place->next)
4487 if (strcmp (place->loader_name, loader_name) == 0)
4492 LT_DLMUTEX_UNLOCK ();