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);
3480 if (errors) return 0;
3482 /* If we found FILENAME, stop searching -- whether we were able to
3483 load the file as a module or not. If the file exists but loading
3484 failed, it is better to return an error message here than to
3485 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
3486 in the module search path. */
3487 if (handle || ((errors > 0) && !file_not_found ()))
3493 #ifdef LTDL_SHLIB_EXT
3494 /* Try appending SHLIB_EXT. */
3495 if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
3498 tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
3502 strcpy (tmp, filename);
3506 tmp[len] = LT_EOS_CHAR;
3509 strcat(tmp, shlib_ext);
3510 errors = try_dlopen (&handle, tmp);
3511 if (errors) return 0;
3513 /* As before, if the file was found but loading failed, return now
3514 with the current error message. */
3515 if (handle || ((errors > 0) && !file_not_found ()))
3522 /* Still here? Then we really did fail to locate any of the file
3524 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3531 lt_argz_insert (pargz, pargz_len, before, entry)
3539 if ((error = argz_insert (pargz, pargz_len, before, entry)))
3544 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
3547 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
3557 lt_argz_insertinorder (pargz, pargz_len, entry)
3566 assert (entry && *entry);
3569 while ((before = argz_next (*pargz, *pargz_len, before)))
3571 int cmp = strcmp (entry, before);
3574 if (cmp == 0) return 0; /* No duplicates! */
3577 return lt_argz_insert (pargz, pargz_len, before, entry);
3581 lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
3590 size_t end_offset = 0;
3598 dir_len = LT_STRLEN (dirnam);
3599 end = dp->d_name + LT_D_NAMLEN(dp);
3601 /* Ignore version numbers. */
3604 for (p = end; p -1 > dp->d_name; --p)
3605 if (strchr (".0123456789", p[-1]) == 0)
3612 /* Ignore filename extension. */
3615 for (p = end -1; p > dp->d_name; --p)
3623 /* Prepend the directory name. */
3624 end_offset = end - dp->d_name;
3625 buf_len = dir_len + 1+ end_offset;
3626 buf = LT_EMALLOC (char, 1+ buf_len);
3632 strcpy (buf, dirnam);
3634 strncat (buf, dp->d_name, end_offset);
3635 buf[buf_len] = LT_EOS_CHAR;
3637 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
3638 if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
3647 list_files_by_dir (dirnam, pargz, pargz_len)
3655 assert (dirnam && *dirnam);
3658 assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
3660 dirp = opendir (dirnam);
3663 struct dirent *dp = 0;
3665 while ((dp = readdir (dirp)))
3666 if (dp->d_name[0] != '.')
3667 if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
3682 /* If there are any files in DIRNAME, call the function passed in
3683 DATA1 (with the name of each file and DATA2 as arguments). */
3685 foreachfile_callback (dirname, data1, data2)
3690 int (*func) LT_PARAMS((const char *filename, lt_ptr data))
3691 = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
3695 size_t argz_len = 0;
3697 if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
3704 while ((filename = argz_next (argz, argz_len, filename)))
3705 if ((is_done = (*func) (filename, data2)))
3716 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
3717 with DATA. The filenames passed to FUNC would be suitable for
3718 passing to lt_dlopenext. The extensions are stripped so that
3719 individual modules do not generate several entries (e.g. libfoo.la,
3720 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
3721 then the same directories that lt_dlopen would search are examined. */
3723 lt_dlforeachfile (search_path, func, data)
3724 const char *search_path;
3725 int (*func) LT_PARAMS ((const char *filename, lt_ptr data));
3732 /* If a specific path was passed, search only the directories
3734 is_done = foreach_dirinpath (search_path, 0,
3735 foreachfile_callback, func, data);
3739 /* Otherwise search the default paths. */
3740 is_done = foreach_dirinpath (user_search_path, 0,
3741 foreachfile_callback, func, data);
3744 is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
3745 foreachfile_callback, func, data);
3748 #ifdef LTDL_SHLIBPATH_VAR
3751 is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0,
3752 foreachfile_callback, func, data);
3755 #ifdef LTDL_SYSSEARCHPATH
3758 is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0,
3759 foreachfile_callback, func, data);
3771 lt_dlhandle cur, last;
3776 /* check whether the handle is valid */
3777 last = cur = handles;
3778 while (cur && handle != cur)
3786 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3791 handle->info.ref_count--;
3793 /* Note that even with resident modules, we must track the ref_count
3794 correctly incase the user decides to reset the residency flag
3795 later (even though the API makes no provision for that at the
3797 if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
3799 lt_user_data data = handle->loader->dlloader_data;
3801 if (handle != handles)
3803 last->next = handle->next;
3807 handles = handle->next;
3810 errors += handle->loader->module_close (data, handle->module);
3811 errors += unload_deplibs(handle);
3813 /* It is up to the callers to free the data itself. */
3814 LT_DLFREE (handle->caller_data);
3816 LT_DLFREE (handle->info.filename);
3817 LT_DLFREE (handle->info.name);
3823 if (LT_DLIS_RESIDENT (handle))
3825 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
3830 LT_DLMUTEX_UNLOCK ();
3836 lt_dlsym (handle, symbol)
3841 char lsym[LT_SYMBOL_LENGTH];
3848 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3854 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
3858 lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
3859 + LT_STRLEN (handle->info.name);
3861 if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
3867 sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
3870 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
3875 data = handle->loader->dlloader_data;
3876 if (handle->info.name)
3878 const char *saved_error;
3880 LT_DLMUTEX_GETERROR (saved_error);
3882 /* this is a libtool module */
3883 if (handle->loader->sym_prefix)
3885 strcpy(sym, handle->loader->sym_prefix);
3886 strcat(sym, handle->info.name);
3890 strcpy(sym, handle->info.name);
3893 strcat(sym, "_LTX_");
3894 strcat(sym, symbol);
3896 /* try "modulename_LTX_symbol" */
3897 address = handle->loader->find_sym (data, handle->module, sym);
3906 LT_DLMUTEX_SETERROR (saved_error);
3909 /* otherwise try "symbol" */
3910 if (handle->loader->sym_prefix)
3912 strcpy(sym, handle->loader->sym_prefix);
3913 strcat(sym, symbol);
3917 strcpy(sym, symbol);
3920 address = handle->loader->find_sym (data, handle->module, sym);
3934 LT_DLMUTEX_GETERROR (error);
3935 LT_DLMUTEX_SETERROR (0);
3937 return error ? error : NULL;
3941 lt_dlpath_insertdir (ppath, before, dir)
3947 char *canonical = 0;
3949 size_t argz_len = 0;
3952 assert (dir && *dir);
3954 if (canonicalize_path (dir, &canonical) != 0)
3960 assert (canonical && *canonical);
3962 /* If *PPATH is empty, set it to DIR. */
3965 assert (!before); /* BEFORE cannot be set without PPATH. */
3966 assert (dir); /* Without DIR, don't call this function! */
3968 *ppath = lt_estrdup (dir);
3975 assert (ppath && *ppath);
3977 if (argzize_path (*ppath, &argz, &argz_len) != 0)
3983 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
3984 if *PPATH is already canonicalized, and hence does not change length
3985 with respect to ARGZ. We canonicalize each entry as it is added to
3986 the search path, and don't call this function with (uncanonicalized)
3987 user paths, so this is a fair assumption. */
3990 assert (*ppath <= before);
3991 assert (before - *ppath <= strlen (*ppath));
3993 before = before - *ppath + argz;
3996 if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
4002 argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
4003 LT_DLMEM_REASSIGN (*ppath, argz);
4006 LT_DLFREE (canonical);
4013 lt_dladdsearchdir (search_dir)
4014 const char *search_dir;
4018 if (search_dir && *search_dir)
4021 if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
4023 LT_DLMUTEX_UNLOCK ();
4030 lt_dlinsertsearchdir (before, search_dir)
4032 const char *search_dir;
4039 if ((before < user_search_path)
4040 || (before >= user_search_path + LT_STRLEN (user_search_path)))
4042 LT_DLMUTEX_UNLOCK ();
4043 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
4046 LT_DLMUTEX_UNLOCK ();
4049 if (search_dir && *search_dir)
4052 if (lt_dlpath_insertdir (&user_search_path,
4053 (char *) before, search_dir) != 0)
4057 LT_DLMUTEX_UNLOCK ();
4064 lt_dlsetsearchpath (search_path)
4065 const char *search_path;
4070 LT_DLFREE (user_search_path);
4071 LT_DLMUTEX_UNLOCK ();
4073 if (!search_path || !LT_STRLEN (search_path))
4079 if (canonicalize_path (search_path, &user_search_path) != 0)
4081 LT_DLMUTEX_UNLOCK ();
4087 lt_dlgetsearchpath ()
4089 const char *saved_path;
4092 saved_path = user_search_path;
4093 LT_DLMUTEX_UNLOCK ();
4099 lt_dlmakeresident (handle)
4106 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4111 LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
4118 lt_dlisresident (handle)
4123 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4127 return LT_DLIS_RESIDENT (handle);
4133 /* --- MODULE INFORMATION --- */
4136 lt_dlgetinfo (handle)
4141 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
4145 return &(handle->info);
4149 lt_dlhandle_next (place)
4152 return place ? place->next : handles;
4156 lt_dlforeach (func, data)
4157 int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data));
4168 lt_dlhandle tmp = cur;
4171 if ((*func) (tmp, data))
4178 LT_DLMUTEX_UNLOCK ();
4184 lt_dlcaller_register ()
4186 static lt_dlcaller_id last_caller_id = 0;
4190 result = ++last_caller_id;
4191 LT_DLMUTEX_UNLOCK ();
4197 lt_dlcaller_set_data (key, handle, data)
4203 lt_ptr stale = (lt_ptr) 0;
4206 /* This needs to be locked so that the caller data can be updated
4207 simultaneously by different threads. */
4210 if (handle->caller_data)
4211 while (handle->caller_data[n_elements].key)
4214 for (i = 0; i < n_elements; ++i)
4216 if (handle->caller_data[i].key == key)
4218 stale = handle->caller_data[i].data;
4223 /* Ensure that there is enough room in this handle's caller_data
4224 array to accept a new element (and an empty end marker). */
4225 if (i == n_elements)
4227 lt_caller_data *temp
4228 = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements);
4236 handle->caller_data = temp;
4238 /* We only need this if we needed to allocate a new caller_data. */
4239 handle->caller_data[i].key = key;
4240 handle->caller_data[1+ i].key = 0;
4243 handle->caller_data[i].data = data;
4246 LT_DLMUTEX_UNLOCK ();
4252 lt_dlcaller_get_data (key, handle)
4256 lt_ptr result = (lt_ptr) 0;
4258 /* This needs to be locked so that the caller data isn't updated by
4259 another thread part way through this function. */
4262 /* Locate the index of the element with a matching KEY. */
4265 for (i = 0; handle->caller_data[i].key; ++i)
4267 if (handle->caller_data[i].key == key)
4269 result = handle->caller_data[i].data;
4275 LT_DLMUTEX_UNLOCK ();
4282 /* --- USER MODULE LOADER API --- */
4286 lt_dlloader_add (place, dlloader, loader_name)
4288 const struct lt_user_dlloader *dlloader;
4289 const char *loader_name;
4292 lt_dlloader *node = 0, *ptr = 0;
4294 if ((dlloader == 0) /* diagnose null parameters */
4295 || (dlloader->module_open == 0)
4296 || (dlloader->module_close == 0)
4297 || (dlloader->find_sym == 0))
4299 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4303 /* Create a new dlloader node with copies of the user callbacks. */
4304 node = LT_EMALLOC (lt_dlloader, 1);
4309 node->loader_name = loader_name;
4310 node->sym_prefix = dlloader->sym_prefix;
4311 node->dlloader_exit = dlloader->dlloader_exit;
4312 node->module_open = dlloader->module_open;
4313 node->module_close = dlloader->module_close;
4314 node->find_sym = dlloader->find_sym;
4315 node->dlloader_data = dlloader->dlloader_data;
4320 /* If there are no loaders, NODE becomes the list! */
4325 /* If PLACE is not set, add NODE to the end of the
4327 for (ptr = loaders; ptr->next; ptr = ptr->next)
4334 else if (loaders == place)
4336 /* If PLACE is the first loader, NODE goes first. */
4342 /* Find the node immediately preceding PLACE. */
4343 for (ptr = loaders; ptr->next != place; ptr = ptr->next)
4348 if (ptr->next != place)
4350 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4355 /* Insert NODE between PTR and PLACE. */
4361 LT_DLMUTEX_UNLOCK ();
4367 lt_dlloader_remove (loader_name)
4368 const char *loader_name;
4370 lt_dlloader *place = lt_dlloader_find (loader_name);
4376 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4382 /* Fail if there are any open modules which use this loader. */
4383 for (handle = handles; handle; handle = handle->next)
4385 if (handle->loader == place)
4387 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
4393 if (place == loaders)
4395 /* PLACE is the first loader in the list. */
4396 loaders = loaders->next;
4400 /* Find the loader before the one being removed. */
4402 for (prev = loaders; prev->next; prev = prev->next)
4404 if (!strcmp (prev->next->loader_name, loader_name))
4411 prev->next = prev->next->next;
4414 if (place->dlloader_exit)
4416 errors = place->dlloader_exit (place->dlloader_data);
4422 LT_DLMUTEX_UNLOCK ();
4428 lt_dlloader_next (place)
4434 next = place ? place->next : loaders;
4435 LT_DLMUTEX_UNLOCK ();
4441 lt_dlloader_name (place)
4444 const char *name = 0;
4449 name = place ? place->loader_name : 0;
4450 LT_DLMUTEX_UNLOCK ();
4454 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4461 lt_dlloader_data (place)
4464 lt_user_data *data = 0;
4469 data = place ? &(place->dlloader_data) : 0;
4470 LT_DLMUTEX_UNLOCK ();
4474 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
4481 lt_dlloader_find (loader_name)
4482 const char *loader_name;
4484 lt_dlloader *place = 0;
4487 for (place = loaders; place; place = place->next)
4489 if (strcmp (place->loader_name, loader_name) == 0)
4494 LT_DLMUTEX_UNLOCK ();