1 /* ltdl.c -- system independent dlopen wrapper
2 Copyright (C) 1998, 1999, 2000 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
70 # define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
72 # define dirent direct
73 # define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
75 # include <sys/ndir.h>
92 # define assert(arg) ((void) 0)
100 /* --- WINDOWS SUPPORT --- */
104 # define LT_GLOBAL_DATA __declspec(dllexport)
106 # define LT_GLOBAL_DATA
109 /* fopen() mode flags for reading a text file */
110 #undef LT_READTEXT_MODE
112 # define LT_READTEXT_MODE "rt"
114 # define LT_READTEXT_MODE "r"
120 /* --- MANIFEST CONSTANTS --- */
123 /* Standard libltdl search path environment variable name */
124 #undef LTDL_SEARCHPATH_VAR
125 #define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH"
127 /* Standard libtool archive file extension. */
128 #undef LTDL_ARCHIVE_EXT
129 #define LTDL_ARCHIVE_EXT ".la"
131 /* max. filename length */
132 #ifndef LT_FILENAME_MAX
133 # define LT_FILENAME_MAX 1024
136 /* This is the maximum symbol size that won't require malloc/free */
137 #undef LT_SYMBOL_LENGTH
138 #define LT_SYMBOL_LENGTH 128
140 /* This accounts for the _LTX_ separator */
141 #undef LT_SYMBOL_OVERHEAD
142 #define LT_SYMBOL_OVERHEAD 5
147 /* --- MEMORY HANDLING --- */
150 /* These are the functions used internally. In addition to making
151 use of the associated function pointers above, they also perform
153 static char *lt_estrdup LT_PARAMS((const char *str));
154 static lt_ptr lt_emalloc LT_PARAMS((size_t size));
155 static lt_ptr lt_erealloc LT_PARAMS((lt_ptr addr, size_t size));
157 static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size));
159 /* These are the pointers that can be changed by the caller: */
160 LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size))
161 = (lt_ptr (*) LT_PARAMS((size_t))) malloc;
162 LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size))
163 = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc;
164 LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr))
165 = (void (*) LT_PARAMS((lt_ptr))) free;
167 /* The following macros reduce the amount of typing needed to cast
169 #define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
170 #define LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))
171 #define LT_DLFREE(p) \
172 LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
174 #define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp)))
175 #define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
177 #define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \
178 if ((p) != (q)) { lt_dlfree (p); (p) = (q); (q) = 0; } \
182 /* --- REPLACEMENT FUNCTIONS --- */
186 #define strdup rpl_strdup
188 static char *strdup LT_PARAMS((const char *str));
198 tmp = LT_DLMALLOC (char, 1+ strlen (str));
212 #define strcmp rpl_strcmp
214 static int strcmp LT_PARAMS((const char *str1, const char *str2));
228 for (;*str1 && *str2; ++str1, ++str2)
234 return (int)(*str1 - *str2);
242 # define strchr index
244 # define strchr rpl_strchr
246 static const char *strchr LT_PARAMS((const char *str, int ch));
255 for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p)
258 return (*p == (char)ch) ? p : 0;
262 #endif /* !HAVE_STRCHR */
268 # define strrchr rindex
270 # define strrchr rpl_strrchr
272 static const char *strrchr LT_PARAMS((const char *str, int ch));
279 const char *p, *q = 0;
281 for (p = str; *p != LT_EOS_CHAR; ++p)
295 /* NOTE: Neither bcopy nor the memcpy implementation below can
296 reliably handle copying in overlapping areas of memory. Use
297 memmove (for which there is a fallback implmentation below)
298 if you need that behaviour. */
302 # define memcpy(dest, src, size) bcopy (src, dest, size)
304 # define memcpy rpl_memcpy
306 static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
309 memcpy (dest, src, size)
316 for (i = 0; i < size; ++i)
324 # endif /* !HAVE_BCOPY */
325 #endif /* !HAVE_MEMCPY */
328 # define memmove rpl_memmove
330 static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
333 memmove (dest, src, size)
341 for (i = 0; i < size; ++i)
346 for (i = size -1; i >= 0; --i)
354 #endif /* !HAVE_MEMMOVE */
357 /* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
358 ``realloc is not entirely portable''
359 In any case we want to use the allocator supplied by the user without
360 burdening them with an lt_dlrealloc function pointer to maintain.
361 Instead implement our own version (with known boundary conditions)
362 using lt_dlmalloc and lt_dlfree. */
365 #define realloc rpl_realloc
374 /* For zero or less bytes, free the original memory */
384 /* Allow reallocation of a NULL pointer. */
385 return lt_dlmalloc (size);
389 /* Allocate a new block, copy and free the old block. */
390 lt_ptr mem = lt_dlmalloc (size);
394 memcpy (mem, ptr, size);
398 /* Note that the contents of PTR are not damaged if there is
399 insufficient memory to realloc. */
405 #if ! HAVE_ARGZ_APPEND
406 # define argz_append rpl_argz_append
408 static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len,
409 const char *buf, size_t buf_len));
412 argz_append (pargz, pargz_len, buf, buf_len)
423 assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
425 /* If nothing needs to be appended, no more work is required. */
429 /* Ensure there is enough room to append BUF_LEN. */
430 argz_len = *pargz_len + buf_len;
431 argz = LT_DLREALLOC (char, *pargz, argz_len);
435 /* Copy characters from BUF after terminating '\0' in ARGZ. */
436 memcpy (argz + *pargz_len, buf, buf_len);
438 /* Assign new values. */
440 *pargz_len = argz_len;
444 #endif /* !HAVE_ARGZ_APPEND */
447 #if ! HAVE_ARGZ_CREATE_SEP
448 # define argz_create_sep rpl_argz_create_sep
450 static error_t argz_create_sep LT_PARAMS((const char *str, int delim,
451 char **pargz, size_t *pargz_len));
454 argz_create_sep (str, delim, pargz, pargz_len)
467 /* Make a copy of STR, but replacing each occurence of
469 argz_len = 1+ LT_STRLEN (str);
475 argz = LT_DLMALLOC (char, argz_len);
479 for (p = str, q = argz; *p != LT_EOS_CHAR; ++p)
483 /* Ignore leading delimiters, and fold consecutive
484 delimiters in STR into a single '\0' in ARGZ. */
485 if ((q > argz) && (q[-1] != LT_EOS_CHAR))
493 /* Copy terminating LT_EOS_CHAR. */
497 /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */
501 /* Assign new values. */
503 *pargz_len = argz_len;
507 #endif /* !HAVE_ARGZ_CREATE_SEP */
510 #if ! HAVE_ARGZ_INSERT
511 # define argz_insert rpl_argz_insert
513 static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len,
514 char *before, const char *entry));
517 argz_insert (pargz, pargz_len, before, entry)
525 assert (entry && *entry);
527 /* Either PARGZ/PARGZ_LEN is empty and BEFORE is NULL,
528 or BEFORE points into an address within the ARGZ vector. */
529 assert ((!*pargz && !*pargz_len && !before)
530 || ((*pargz <= before) && (before < (*pargz + *pargz_len))));
532 /* No BEFORE address indicates ENTRY should be inserted after the
533 current last element. */
535 return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry));
537 /* This probably indicates a programmer error, but to preserve
538 semantics, scan back to the start of an entry if BEFORE points
539 into the middle of it. */
540 while ((before >= *pargz) && (before[-1] != LT_EOS_CHAR))
544 size_t entry_len = 1+ LT_STRLEN (entry);
545 size_t argz_len = *pargz_len + entry_len;
546 size_t offset = before - *pargz;
547 char *argz = LT_DLREALLOC (char, *pargz, argz_len);
552 /* Make BEFORE point to the equivalent offset in ARGZ that it
553 used to have in *PARGZ incase realloc() moved the block. */
554 before = argz + offset;
556 /* Move the ARGZ entries starting at BEFORE up into the new
557 space at the end -- making room to copy ENTRY into the
559 memmove (before + entry_len, before, *pargz_len - offset);
560 memcpy (before, entry, entry_len);
562 /* Assign new values. */
564 *pargz_len = argz_len;
569 #endif /* !HAVE_ARGZ_INSERT */
573 # define argz_next rpl_argz_next
575 static char *argz_next LT_PARAMS((char *argz, size_t argz_len,
579 argz_next (argz, argz_len, entry)
584 assert ((argz && argz_len) || (!argz && !argz_len));
588 /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
589 within the ARGZ vector. */
590 assert ((!argz && !argz_len)
591 || ((argz <= entry) && (entry < (argz + argz_len))));
593 /* Move to the char immediately after the terminating
595 entry = 1+ strchr (entry, LT_EOS_CHAR);
597 /* Return either the new ENTRY, or else NULL if ARGZ is
599 return (entry >= argz + argz_len) ? 0 : (char *) entry;
603 /* This should probably be flagged as a programmer error,
604 since starting an argz_next loop with the iterator set
605 to ARGZ is safer. To preserve semantics, handle the NULL
606 case by returning the start of ARGZ (if any). */
613 #endif /* !HAVE_ARGZ_NEXT */
617 #if ! HAVE_ARGZ_STRINGIFY
618 # define argz_stringify rpl_argz_stringify
620 static void argz_stringify LT_PARAMS((char *argz, size_t argz_len,
624 argz_stringify (argz, argz_len, sep)
629 assert ((argz && argz_len) || (!argz && !argz_len));
633 --argz_len; /* don't stringify the terminating EOS */
634 while (--argz_len > 0)
636 if (argz[argz_len] == LT_EOS_CHAR)
637 argz[argz_len] = sep;
641 #endif /* !HAVE_ARGZ_STRINGIFY */
646 /* --- TYPE DEFINITIONS -- */
649 /* This type is used for the array of caller data sets in each handler. */
658 /* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
661 /* Extract the diagnostic strings from the error table macro in the same
662 order as the enumerated indices in ltdl.h. */
664 static const char *lt_dlerror_strings[] =
666 #define LT_ERROR(name, diagnostic) (diagnostic),
673 /* This structure is used for the list of registered loaders. */
675 struct lt_dlloader *next;
676 const char *loader_name; /* identifying name for each loader */
677 const char *sym_prefix; /* prefix for symbols */
678 lt_module_open *module_open;
679 lt_module_close *module_close;
680 lt_find_sym *find_sym;
681 lt_dlloader_exit *dlloader_exit;
682 lt_user_data dlloader_data;
685 struct lt_dlhandle_struct {
686 struct lt_dlhandle_struct *next;
687 lt_dlloader *loader; /* dlopening interface */
689 int depcount; /* number of dependencies */
690 lt_dlhandle *deplibs; /* dependencies */
691 lt_module module; /* system module handle */
692 lt_ptr system; /* system specific data */
693 lt_caller_data *caller_data; /* per caller associated data */
694 int flags; /* various boolean stats */
697 /* Various boolean flags can be stored in the flags field of an
698 lt_dlhandle_struct... */
699 #define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
700 #define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
702 #define LT_DLRESIDENT_FLAG (0x01 << 0)
703 /* ...add more flags here... */
705 #define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
708 #define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
710 static const char objdir[] = LTDL_OBJDIR;
711 static const char archive_ext[] = LTDL_ARCHIVE_EXT;
712 #ifdef LTDL_SHLIB_EXT
713 static const char shlib_ext[] = LTDL_SHLIB_EXT;
715 #ifdef LTDL_SYSSEARCHPATH
716 static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
722 /* --- MUTEX LOCKING --- */
725 /* Macros to make it easier to run the lock functions only if they have
726 been registered. The reason for the complicated lock macro is to
727 ensure that the stored error message from the last error is not
728 accidentally erased if the current function doesn't generate an
730 #define LT_DLMUTEX_LOCK() LT_STMT_START { \
731 if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \
733 #define LT_DLMUTEX_UNLOCK() LT_STMT_START { \
734 if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
736 #define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \
737 if (lt_dlmutex_seterror_func) \
738 (*lt_dlmutex_seterror_func) (errormsg); \
739 else lt_dllast_error = (errormsg); } LT_STMT_END
740 #define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \
741 if (lt_dlmutex_seterror_func) \
742 (errormsg) = (*lt_dlmutex_geterror_func) (); \
743 else (errormsg) = lt_dllast_error; } LT_STMT_END
745 /* The mutex functions stored here are global, and are necessarily the
746 same for all threads that wish to share access to libltdl. */
747 static lt_dlmutex_lock *lt_dlmutex_lock_func = 0;
748 static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0;
749 static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0;
750 static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0;
751 static const char *lt_dllast_error = 0;
754 /* Either set or reset the mutex functions. Either all the arguments must
755 be valid functions, or else all can be NULL to turn off locking entirely.
756 The registered functions should be manipulating a static global lock
757 from the lock() and unlock() callbacks, which needs to be reentrant. */
759 lt_dlmutex_register (lock, unlock, seterror, geterror)
760 lt_dlmutex_lock *lock;
761 lt_dlmutex_unlock *unlock;
762 lt_dlmutex_seterror *seterror;
763 lt_dlmutex_geterror *geterror;
765 lt_dlmutex_unlock *old_unlock = unlock;
768 /* Lock using the old lock() callback, if any. */
771 if ((lock && unlock && seterror && geterror)
772 || !(lock || unlock || seterror || geterror))
774 lt_dlmutex_lock_func = lock;
775 lt_dlmutex_unlock_func = unlock;
776 lt_dlmutex_geterror_func = geterror;
780 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
784 /* Use the old unlock() callback we saved earlier, if any. Otherwise
785 record any errors using internal storage. */
789 /* Return the number of errors encountered during the execution of
797 /* --- ERROR HANDLING --- */
800 static const char **user_error_strings = 0;
801 static int errorcount = LT_ERROR_MAX;
804 lt_dladderror (diagnostic)
805 const char *diagnostic;
809 const char **temp = (const char **) 0;
815 errindex = errorcount - LT_ERROR_MAX;
816 temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex);
819 user_error_strings = temp;
820 user_error_strings[errindex] = diagnostic;
821 result = errorcount++;
824 LT_DLMUTEX_UNLOCK ();
830 lt_dlseterror (errindex)
837 if (errindex >= errorcount || errindex < 0)
839 /* Ack! Error setting the error message! */
840 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
843 else if (errindex < LT_ERROR_MAX)
845 /* No error setting the error message! */
846 LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]);
850 /* No error setting the error message! */
851 LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]);
854 LT_DLMUTEX_UNLOCK ();
863 lt_ptr mem = lt_dlmalloc (size);
865 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
870 lt_erealloc (addr, size)
874 lt_ptr mem = realloc (addr, size);
876 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
884 char *dup = strdup (str);
885 if (LT_STRLEN (str) && !dup)
886 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
893 /* --- DLOPEN() INTERFACE LOADER --- */
896 /* The Cygwin dlopen implementation prints a spurious error message to
897 stderr if its call to LoadLibrary() fails for any reason. We can
898 mitigate this by not using the Cygwin implementation, and falling
899 back to our own LoadLibrary() wrapper. */
900 #if HAVE_LIBDL && !defined(__CYGWIN__)
902 /* dynamic linking with dlopen/dlsym */
913 # define LT_GLOBAL RTLD_GLOBAL
916 # define LT_GLOBAL DL_GLOBAL
918 #endif /* !RTLD_GLOBAL */
921 #endif /* !LT_GLOBAL */
923 /* We may have to define LT_LAZY_OR_NOW in the command line if we
924 find out it does not work in some platform. */
925 #ifndef LT_LAZY_OR_NOW
927 # define LT_LAZY_OR_NOW RTLD_LAZY
930 # define LT_LAZY_OR_NOW DL_LAZY
932 # endif /* !RTLD_LAZY */
934 #ifndef LT_LAZY_OR_NOW
936 # define LT_LAZY_OR_NOW RTLD_NOW
939 # define LT_LAZY_OR_NOW DL_NOW
941 # endif /* !RTLD_NOW */
943 #ifndef LT_LAZY_OR_NOW
944 # define LT_LAZY_OR_NOW 0
945 #endif /* !LT_LAZY_OR_NOW */
948 # define DLERROR(arg) dlerror ()
950 # define DLERROR(arg) LT_DLSTRERROR (arg)
954 sys_dl_open (loader_data, filename)
955 lt_user_data loader_data;
956 const char *filename;
958 lt_module module = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW);
962 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN));
969 sys_dl_close (loader_data, module)
970 lt_user_data loader_data;
975 if (dlclose (module) != 0)
977 LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
985 sys_dl_sym (loader_data, module, symbol)
986 lt_user_data loader_data;
990 lt_ptr address = dlsym (module, symbol);
994 LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
1000 static struct lt_user_dlloader sys_dl =
1007 sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 };
1010 #endif /* HAVE_LIBDL */
1014 /* --- SHL_LOAD() INTERFACE LOADER --- */
1018 /* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
1024 /* some flags are missing on some systems, so we provide
1025 * harmless defaults.
1028 * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
1029 * BIND_DEFERRED - Delay code symbol resolution until actual reference.
1032 * BIND_FIRST - Place the library at the head of the symbol search
1034 * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all
1035 * unsatisfied symbols as fatal. This flag allows
1036 * binding of unsatisfied code symbols to be deferred
1038 * [Perl: For certain libraries, like DCE, deferred
1039 * binding often causes run time problems. Adding
1040 * BIND_NONFATAL to BIND_IMMEDIATE still allows
1041 * unresolved references in situations like this.]
1042 * BIND_NOSTART - Do not call the initializer for the shared library
1043 * when the library is loaded, nor on a future call to
1045 * BIND_VERBOSE - Print verbose messages concerning possible
1046 * unsatisfied symbols.
1048 * hp9000s700/hp9000s800:
1049 * BIND_RESTRICTED - Restrict symbols visible by the library to those
1050 * present at library load time.
1051 * DYNAMIC_PATH - Allow the loader to dynamically search for the
1052 * library specified by the path argument.
1055 #ifndef DYNAMIC_PATH
1056 # define DYNAMIC_PATH 0
1058 #ifndef BIND_RESTRICTED
1059 # define BIND_RESTRICTED 0
1062 #define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
1065 sys_shl_open (loader_data, filename)
1066 lt_user_data loader_data;
1067 const char *filename;
1069 static shl_t self = (shl_t) 0;
1070 lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
1072 /* Since searching for a symbol against a NULL module handle will also
1073 look in everything else that was already loaded and exported with
1074 the -E compiler flag, we always cache a handle saved before any
1075 modules are loaded. */
1079 shl_findsym (&self, "main", TYPE_UNDEFINED, &address);
1088 module = shl_load (filename, LT_BIND_FLAGS, 0L);
1092 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1100 sys_shl_close (loader_data, module)
1101 lt_user_data loader_data;
1106 if (module && (shl_unload ((shl_t) (module)) != 0))
1108 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1116 sys_shl_sym (loader_data, module, symbol)
1117 lt_user_data loader_data;
1123 /* sys_shl_open should never return a NULL module handle */
1124 if (module == (lt_module) 0)
1126 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
1128 else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))
1132 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1139 static struct lt_user_dlloader sys_shl = {
1140 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0
1143 #endif /* HAVE_SHL_LOAD */
1148 /* --- LOADLIBRARY() INTERFACE LOADER --- */
1152 /* dynamic linking for Win32 */
1154 #include <windows.h>
1156 /* Forward declaration; required to implement handle search below. */
1157 static lt_dlhandle handles;
1160 sys_wll_open (loader_data, filename)
1161 lt_user_data loader_data;
1162 const char *filename;
1165 lt_module module = 0;
1166 const char *errormsg = 0;
1167 char *searchname = 0;
1169 char self_name_buf[MAX_PATH];
1173 /* Get the name of main module */
1175 GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf));
1176 filename = ext = self_name_buf;
1180 ext = strrchr (filename, '.');
1185 /* FILENAME already has an extension. */
1186 searchname = lt_estrdup (filename);
1190 /* Append a `.' to stop Windows from adding an
1191 implicit `.dll' extension. */
1192 searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename));
1194 sprintf (searchname, "%s.", filename);
1201 char wpath[MAX_PATH];
1202 cygwin_conv_to_full_win32_path(searchname, wpath);
1203 module = LoadLibrary(wpath);
1206 module = LoadLibrary (searchname);
1208 LT_DLFREE (searchname);
1210 /* libltdl expects this function to fail if it is unable
1211 to physically load the library. Sadly, LoadLibrary
1212 will search the loaded libraries for a match and return
1213 one of them if the path search load fails.
1215 We check whether LoadLibrary is returning a handle to
1216 an already loaded module, and simulate failure if we
1228 if (cur->module == module)
1235 LT_DLMUTEX_UNLOCK ();
1239 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1247 sys_wll_close (loader_data, module)
1248 lt_user_data loader_data;
1253 if (FreeLibrary(module) == 0)
1255 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1263 sys_wll_sym (loader_data, module, symbol)
1264 lt_user_data loader_data;
1268 lt_ptr address = GetProcAddress (module, symbol);
1272 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1278 static struct lt_user_dlloader sys_wll = {
1279 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0
1282 #endif /* __WINDOWS__ */
1287 /* --- LOAD_ADD_ON() INTERFACE LOADER --- */
1292 /* dynamic linking for BeOS */
1294 #include <kernel/image.h>
1297 sys_bedl_open (loader_data, filename)
1298 lt_user_data loader_data;
1299 const char *filename;
1305 image = load_add_on (filename);
1311 if (get_next_image_info (0, &cookie, &info) == B_OK)
1312 image = load_add_on (info.name);
1317 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1321 return (lt_module) image;
1325 sys_bedl_close (loader_data, module)
1326 lt_user_data loader_data;
1331 if (unload_add_on ((image_id) module) != B_OK)
1333 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1341 sys_bedl_sym (loader_data, module, symbol)
1342 lt_user_data loader_data;
1347 image_id image = (image_id) module;
1349 if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
1351 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1358 static struct lt_user_dlloader sys_bedl = {
1359 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0
1362 #endif /* __BEOS__ */
1367 /* --- DLD_LINK() INTERFACE LOADER --- */
1372 /* dynamic linking with dld */
1379 sys_dld_open (loader_data, filename)
1380 lt_user_data loader_data;
1381 const char *filename;
1383 lt_module module = strdup (filename);
1385 if (dld_link (filename) != 0)
1387 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1396 sys_dld_close (loader_data, module)
1397 lt_user_data loader_data;
1402 if (dld_unlink_by_file ((char*)(module), 1) != 0)
1404 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1416 sys_dld_sym (loader_data, module, symbol)
1417 lt_user_data loader_data;
1421 lt_ptr address = dld_get_func (symbol);
1425 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1431 static struct lt_user_dlloader sys_dld = {
1432 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0
1435 #endif /* HAVE_DLD */
1440 /* --- DLPREOPEN() INTERFACE LOADER --- */
1443 /* emulate dynamic linking using preloaded_symbols */
1445 typedef struct lt_dlsymlists_t
1447 struct lt_dlsymlists_t *next;
1448 const lt_dlsymlist *syms;
1451 static const lt_dlsymlist *default_preloaded_symbols = 0;
1452 static lt_dlsymlists_t *preloaded_symbols = 0;
1455 presym_init (loader_data)
1456 lt_user_data loader_data;
1462 preloaded_symbols = 0;
1463 if (default_preloaded_symbols)
1465 errors = lt_dlpreload (default_preloaded_symbols);
1468 LT_DLMUTEX_UNLOCK ();
1474 presym_free_symlists ()
1476 lt_dlsymlists_t *lists;
1480 lists = preloaded_symbols;
1483 lt_dlsymlists_t *tmp = lists;
1485 lists = lists->next;
1488 preloaded_symbols = 0;
1490 LT_DLMUTEX_UNLOCK ();
1496 presym_exit (loader_data)
1497 lt_user_data loader_data;
1499 presym_free_symlists ();
1504 presym_add_symlist (preloaded)
1505 const lt_dlsymlist *preloaded;
1507 lt_dlsymlists_t *tmp;
1508 lt_dlsymlists_t *lists;
1513 lists = preloaded_symbols;
1516 if (lists->syms == preloaded)
1520 lists = lists->next;
1523 tmp = LT_EMALLOC (lt_dlsymlists_t, 1);
1526 memset (tmp, 0, sizeof(lt_dlsymlists_t));
1527 tmp->syms = preloaded;
1528 tmp->next = preloaded_symbols;
1529 preloaded_symbols = tmp;
1537 LT_DLMUTEX_UNLOCK ();
1542 presym_open (loader_data, filename)
1543 lt_user_data loader_data;
1544 const char *filename;
1546 lt_dlsymlists_t *lists;
1547 lt_module module = (lt_module) 0;
1550 lists = preloaded_symbols;
1554 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
1558 /* Can't use NULL as the reflective symbol header, as NULL is
1559 used to mark the end of the entire symbol list. Self-dlpreopened
1560 symbols follow this magic number, chosen to be an unlikely
1561 clash with a real module name. */
1564 filename = "@PROGRAM@";
1569 const lt_dlsymlist *syms = lists->syms;
1573 if (!syms->address && strcmp(syms->name, filename) == 0)
1575 module = (lt_module) syms;
1581 lists = lists->next;
1584 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
1587 LT_DLMUTEX_UNLOCK ();
1592 presym_close (loader_data, module)
1593 lt_user_data loader_data;
1596 /* Just to silence gcc -Wall */
1602 presym_sym (loader_data, module, symbol)
1603 lt_user_data loader_data;
1607 lt_dlsymlist *syms = (lt_dlsymlist*) module;
1610 while (syms->address)
1612 if (strcmp(syms->name, symbol) == 0)
1614 return syms->address;
1620 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1625 static struct lt_user_dlloader presym = {
1626 0, presym_open, presym_close, presym_sym, presym_exit, 0
1633 /* --- DYNAMIC MODULE LOADING --- */
1636 /* The type of a function used at each iteration of foreach_dirinpath(). */
1637 typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1,
1640 static int foreach_dirinpath LT_PARAMS((const char *search_path,
1641 const char *base_name,
1642 foreach_callback_func *func,
1643 lt_ptr data1, lt_ptr data2));
1645 static int find_file_callback LT_PARAMS((char *filename, lt_ptr data,
1647 static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data,
1649 static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1,
1653 static int canonicalize_path LT_PARAMS((const char *path,
1654 char **pcanonical));
1655 static int argzize_path LT_PARAMS((const char *path,
1657 size_t *pargz_len));
1658 static FILE *find_file LT_PARAMS((const char *search_path,
1659 const char *base_name,
1661 static lt_dlhandle *find_handle LT_PARAMS((const char *search_path,
1662 const char *base_name,
1663 lt_dlhandle *handle));
1664 static int find_module LT_PARAMS((lt_dlhandle *handle,
1668 const char *old_name,
1670 static int free_vars LT_PARAMS((char *dlname, char *oldname,
1671 char *libdir, char *deplibs));
1672 static int load_deplibs LT_PARAMS((lt_dlhandle handle,
1674 static int trim LT_PARAMS((char **dest,
1676 static int try_dlopen LT_PARAMS((lt_dlhandle *handle,
1677 const char *filename));
1678 static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle,
1679 const char *filename));
1680 static int unload_deplibs LT_PARAMS((lt_dlhandle handle));
1681 static int lt_argz_insert LT_PARAMS((char **pargz,
1684 const char *entry));
1685 static int lt_argz_insertinorder LT_PARAMS((char **pargz,
1687 const char *entry));
1688 static int lt_dlpath_insertdir LT_PARAMS((char **ppath,
1692 static char *user_search_path= 0;
1693 static lt_dlloader *loaders = 0;
1694 static lt_dlhandle handles = 0;
1695 static int initialized = 0;
1697 /* Initialize libltdl. */
1705 /* Initialize only at first call. */
1706 if (++initialized == 1)
1709 user_search_path = 0; /* empty search path */
1711 #if HAVE_LIBDL && !defined(__CYGWIN__)
1712 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen");
1715 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen");
1718 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen");
1721 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen");
1724 errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld");
1726 errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload");
1728 if (presym_init (presym.dlloader_data))
1730 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
1733 else if (errors != 0)
1735 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
1740 LT_DLMUTEX_UNLOCK ();
1746 lt_dlpreload (preloaded)
1747 const lt_dlsymlist *preloaded;
1753 errors = presym_add_symlist (preloaded);
1757 presym_free_symlists();
1760 if (default_preloaded_symbols)
1762 errors = lt_dlpreload (default_preloaded_symbols);
1764 LT_DLMUTEX_UNLOCK ();
1771 lt_dlpreload_default (preloaded)
1772 const lt_dlsymlist *preloaded;
1775 default_preloaded_symbols = preloaded;
1776 LT_DLMUTEX_UNLOCK ();
1783 /* shut down libltdl */
1784 lt_dlloader *loader;
1792 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
1797 /* shut down only at last call. */
1798 if (--initialized == 0)
1802 while (handles && LT_DLIS_RESIDENT (handles))
1804 handles = handles->next;
1807 /* close all modules */
1808 for (level = 1; handles; ++level)
1810 lt_dlhandle cur = handles;
1811 int saw_nonresident = 0;
1815 lt_dlhandle tmp = cur;
1817 if (!LT_DLIS_RESIDENT (tmp))
1818 saw_nonresident = 1;
1819 if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level)
1821 if (lt_dlclose (tmp))
1827 /* done if only resident modules are left */
1828 if (!saw_nonresident)
1832 /* close all loaders */
1835 lt_dlloader *next = loader->next;
1836 lt_user_data data = loader->dlloader_data;
1837 if (loader->dlloader_exit && loader->dlloader_exit (data))
1842 LT_DLMEM_REASSIGN (loader, next);
1848 LT_DLMUTEX_UNLOCK ();
1853 tryall_dlopen (handle, filename)
1854 lt_dlhandle *handle;
1855 const char *filename;
1858 lt_dlloader *loader;
1859 const char *saved_error;
1862 LT_DLMUTEX_GETERROR (saved_error);
1868 /* check whether the module was already opened */
1871 /* try to dlopen the program itself? */
1872 if (!cur->info.filename && !filename)
1877 if (cur->info.filename && filename
1878 && strcmp (cur->info.filename, filename) == 0)
1888 ++cur->info.ref_count;
1896 cur->info.filename = lt_estrdup (filename);
1897 if (!cur->info.filename)
1905 cur->info.filename = 0;
1910 lt_user_data data = loader->dlloader_data;
1912 cur->module = loader->module_open (data, filename);
1914 if (cur->module != 0)
1918 loader = loader->next;
1923 LT_DLFREE (cur->info.filename);
1928 cur->loader = loader;
1929 LT_DLMUTEX_SETERROR (saved_error);
1932 LT_DLMUTEX_UNLOCK ();
1938 tryall_dlopen_module (handle, prefix, dirname, dlname)
1939 lt_dlhandle *handle;
1941 const char *dirname;
1946 size_t filename_len = 0;
1947 size_t dirname_len = LT_STRLEN (dirname);
1952 #ifdef LT_DIRSEP_CHAR
1953 /* Only canonicalized names (i.e. with DIRSEP chars already converted)
1954 should make it into this function: */
1955 assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
1958 if (dirname[dirname_len -1] == '/')
1960 filename_len = dirname_len + 1 + LT_STRLEN (dlname);
1962 /* Allocate memory, and combine DIRNAME and MODULENAME into it.
1963 The PREFIX (if any) is handled below. */
1964 filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);
1968 sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
1970 /* Now that we have combined DIRNAME and MODULENAME, if there is
1971 also a PREFIX to contend with, simply recurse with the arguments
1972 shuffled. Otherwise, attempt to open FILENAME as a module. */
1975 error += tryall_dlopen_module (handle,
1976 (const char *) 0, prefix, filename);
1978 else if (tryall_dlopen (handle, filename) != 0)
1983 LT_DLFREE (filename);
1988 find_module (handle, dir, libdir, dlname, old_name, installed)
1989 lt_dlhandle *handle;
1993 const char *old_name;
1996 /* Try to open the old library first; if it was dlpreopened,
1997 we want the preopened version of it, even if a dlopenable
1998 module is available. */
1999 if (old_name && tryall_dlopen (handle, old_name) == 0)
2004 /* Try to open the dynamic library. */
2007 /* try to open the installed module */
2008 if (installed && libdir)
2010 if (tryall_dlopen_module (handle,
2011 (const char *) 0, libdir, dlname) == 0)
2015 /* try to open the not-installed module */
2018 if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
2022 /* maybe it was moved to another directory */
2024 if (tryall_dlopen_module (handle,
2025 (const char *) 0, dir, dlname) == 0)
2035 canonicalize_path (path, pcanonical)
2039 char *canonical = 0;
2041 assert (path && *path);
2042 assert (pcanonical);
2044 canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));
2051 for (src = 0; path[src] != LT_EOS_CHAR; ++src)
2053 /* Path separators are not copied to the beginning or end of
2054 the destination, or if another separator would follow
2056 if (path[src] == LT_PATHSEP_CHAR)
2059 || (path[1+ src] == LT_PATHSEP_CHAR)
2060 || (path[1+ src] == LT_EOS_CHAR))
2064 /* Anything other than a directory separator is copied verbatim. */
2065 if ((path[src] != '/')
2066 #ifdef LT_DIRSEP_CHAR
2067 && (path[src] != LT_DIRSEP_CHAR)
2071 canonical[dest++] = path[src];
2073 /* Directory separators are converted and copied only if they are
2074 not at the end of a path -- i.e. before a path separator or
2076 else if ((path[1+ src] != LT_PATHSEP_CHAR)
2077 && (path[1+ src] != LT_EOS_CHAR)
2078 #ifdef LT_DIRSEP_CHAR
2079 && (path[1+ src] != LT_DIRSEP_CHAR)
2081 && (path[1+ src] != '/'))
2083 canonical[dest++] = '/';
2087 /* Add an end-of-string marker at the end. */
2088 canonical[dest] = LT_EOS_CHAR;
2091 /* Assign new value. */
2092 *pcanonical = canonical;
2098 argzize_path (path, pargz, pargz_len)
2109 if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
2114 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2117 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
2127 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
2128 of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
2129 non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
2130 it is appended to each SEARCH_PATH element before FUNC is called. */
2132 foreach_dirinpath (search_path, base_name, func, data1, data2)
2133 const char *search_path;
2134 const char *base_name;
2135 foreach_callback_func *func;
2140 int filenamesize = 0;
2141 int lenbase = LT_STRLEN (base_name);
2142 size_t argz_len = 0;
2144 char * filename = 0;
2145 char * canonical = 0;
2149 if (!search_path || !*search_path)
2151 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2155 if (canonicalize_path (search_path, &canonical) != 0)
2158 if (argzize_path (canonical, &argz, &argz_len) != 0)
2163 while ((dir_name = argz_next (argz, argz_len, dir_name)))
2165 int lendir = LT_STRLEN (dir_name);
2167 if (lendir +1 +lenbase >= filenamesize)
2169 LT_DLFREE (filename);
2170 filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */
2171 filename = LT_EMALLOC (char, filenamesize);
2176 strncpy (filename, dir_name, lendir);
2177 if (base_name && *base_name)
2179 if (filename[lendir -1] != '/')
2180 filename[lendir++] = '/';
2181 strcpy (filename +lendir, base_name);
2184 if ((result = (*func) (filename, data1, data2)))
2193 LT_DLFREE (canonical);
2194 LT_DLFREE (filename);
2196 LT_DLMUTEX_UNLOCK ();
2201 /* If FILEPATH can be opened, store the name of the directory component
2202 in DATA1, and the opened FILE* structure address in DATA2. Otherwise
2203 DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
2205 find_file_callback (filename, data1, data2)
2210 char **pdir = (char **) data1;
2211 FILE **pfile = (FILE **) data2;
2214 assert (filename && *filename);
2218 if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
2220 char *dirend = strrchr (filename, '/');
2222 if (dirend > filename)
2223 *dirend = LT_EOS_CHAR;
2226 *pdir = lt_estrdup (filename);
2227 is_done = (*pdir == 0) ? -1 : 1;
2234 find_file (search_path, base_name, pdir)
2235 const char *search_path;
2236 const char *base_name;
2241 foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
2247 find_handle_callback (filename, data, ignored)
2252 lt_dlhandle *handle = (lt_dlhandle *) data;
2253 int got_access_error = access (filename, R_OK);
2255 /* Bail out if file cannot be read... */
2256 if (got_access_error)
2259 /* Try to dlopen the file, but do not continue searching in any
2261 if (tryall_dlopen (handle, filename) != 0)
2267 /* If HANDLE was found return it, otherwise return 0. If HANDLE was
2268 found but could not be opened, *HANDLE will be set to 0. */
2269 static lt_dlhandle *
2270 find_handle (search_path, base_name, handle)
2271 const char *search_path;
2272 const char *base_name;
2273 lt_dlhandle *handle;
2278 if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
2286 load_deplibs (handle, deplibs)
2290 #if LTDL_DLOPEN_DEPLIBS
2291 char *p, *save_search_path = 0;
2298 handle->depcount = 0;
2300 #if LTDL_DLOPEN_DEPLIBS
2308 if (user_search_path)
2310 save_search_path = lt_estrdup (user_search_path);
2311 if (!save_search_path)
2315 /* extract search paths and count deplibs */
2319 if (!isspace ((int) *p))
2322 while (*end && !isspace((int) *end))
2327 if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
2330 *end = 0; /* set a temporary string terminator */
2331 if (lt_dladdsearchdir(p+2))
2350 /* restore the old search path */
2351 LT_DLFREE (user_search_path);
2352 user_search_path = save_search_path;
2354 LT_DLMUTEX_UNLOCK ();
2362 names = LT_EMALLOC (char *, depcount * sizeof (char*));
2366 /* now only extract the actual deplibs */
2371 if (isspace ((int) *p))
2378 while (*end && !isspace ((int) *end))
2383 if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
2387 *end = 0; /* set a temporary string terminator */
2388 if (strncmp(p, "-l", 2) == 0)
2390 size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
2391 name = LT_EMALLOC (char, 1+ name_len);
2393 sprintf (name, "lib%s", p+2);
2396 name = lt_estrdup(p);
2401 names[depcount++] = name;
2408 /* load the deplibs (in reverse order)
2409 At this stage, don't worry if the deplibs do not load correctly,
2410 they may already be statically linked into the loading application
2411 for instance. There will be a more enlightening error message
2412 later on if the loaded module cannot resolve all of its symbols. */
2417 handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount);
2418 if (!handle->deplibs)
2421 for (i = 0; i < depcount; ++i)
2423 handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
2424 if (handle->deplibs[j])
2430 handle->depcount = j; /* Number of successfully loaded deplibs */
2435 for (i = 0; i < depcount; ++i)
2437 LT_DLFREE (names[i]);
2448 unload_deplibs (handle)
2454 if (handle->depcount)
2456 for (i = 0; i < handle->depcount; ++i)
2458 if (!LT_DLIS_RESIDENT (handle->deplibs[i]))
2460 errors += lt_dlclose (handle->deplibs[i]);
2473 /* remove the leading and trailing "'" from str
2474 and store the result in dest */
2475 const char *end = strrchr (str, '\'');
2476 int len = LT_STRLEN (str);
2481 if (len > 3 && str[0] == '\'')
2483 tmp = LT_EMALLOC (char, end - str);
2487 strncpy(tmp, &str[1], (end - str) - 1);
2488 tmp[len-3] = LT_EOS_CHAR;
2500 free_vars (dlname, oldname, libdir, deplibs)
2507 LT_DLFREE (oldname);
2509 LT_DLFREE (deplibs);
2515 try_dlopen (phandle, filename)
2516 lt_dlhandle *phandle;
2517 const char *filename;
2519 const char * ext = 0;
2520 const char * saved_error = 0;
2521 char * canonical = 0;
2522 char * base_name = 0;
2526 lt_dlhandle newhandle;
2529 assert (*phandle == 0);
2531 LT_DLMUTEX_GETERROR (saved_error);
2536 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
2540 memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
2541 newhandle = *phandle;
2543 /* lt_dlclose()ing yourself is very bad! Disallow it. */
2544 LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
2546 if (tryall_dlopen (&newhandle, 0) != 0)
2548 LT_DLFREE (*phandle);
2552 goto register_handle;
2555 assert (filename && *filename);
2557 /* Doing this immediately allows internal functions to safely
2558 assume only canonicalized paths are passed. */
2559 if (canonicalize_path (filename, &canonical) != 0)
2565 /* If the canonical module name is a path (relative or absolute)
2566 then split it into a directory part and a name part. */
2567 base_name = strrchr (canonical, '/');
2570 size_t dirlen = (1+ base_name) - canonical;
2572 dir = LT_EMALLOC (char, 1+ dirlen);
2579 strncpy (dir, canonical, dirlen);
2580 dir[dirlen] = LT_EOS_CHAR;
2585 LT_DLMEM_REASSIGN (base_name, canonical);
2587 assert (base_name && *base_name);
2589 /* Check whether we are opening a libtool module (.la extension). */
2590 ext = strrchr (base_name, '.');
2591 if (ext && strcmp (ext, archive_ext) == 0)
2593 /* this seems to be a libtool module */
2596 char * old_name = 0;
2603 /* if we can't find the installed flag, it is probably an
2604 installed libtool archive, produced with an old version
2608 /* extract the module name from the file name */
2609 name = LT_EMALLOC (char, ext - base_name + 1);
2616 /* canonicalize the module name */
2617 for (i = 0; i < ext - base_name; ++i)
2619 if (isalnum ((int)(base_name[i])))
2621 name[i] = base_name[i];
2628 name[ext - base_name] = LT_EOS_CHAR;
2630 /* Now try to open the .la file. If there is no directory name
2631 component, try to find it first in user_search_path and then other
2632 prescribed paths. Otherwise (or in any case if the module was not
2633 yet found) try opening just the module name as passed. */
2636 const char *search_path;
2639 search_path = user_search_path;
2641 file = find_file (user_search_path, base_name, &dir);
2642 LT_DLMUTEX_UNLOCK ();
2646 search_path = getenv (LTDL_SEARCHPATH_VAR);
2648 file = find_file (search_path, base_name, &dir);
2651 #ifdef LTDL_SHLIBPATH_VAR
2654 search_path = getenv (LTDL_SHLIBPATH_VAR);
2656 file = find_file (search_path, base_name, &dir);
2659 #ifdef LTDL_SYSSEARCHPATH
2660 if (!file && sys_search_path)
2662 file = find_file (sys_search_path, base_name, &dir);
2668 file = fopen (filename, LT_READTEXT_MODE);
2671 /* If we didn't find the file by now, it really isn't there. Set
2672 the status flag, and bail out. */
2675 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2680 line_len = LT_FILENAME_MAX;
2681 line = LT_EMALLOC (char, line_len);
2689 /* read the .la file */
2690 while (!feof (file))
2692 if (!fgets (line, line_len, file))
2697 /* Handle the case where we occasionally need to read a line
2698 that is longer than the initial buffer size. */
2699 while (line[LT_STRLEN(line) -1] != '\n')
2701 line = LT_DLREALLOC (char, line, line_len *2);
2702 if (!fgets (&line[line_len -1], line_len +1, file))
2709 if (line[0] == '\n' || line[0] == '#')
2715 #define STR_DLNAME "dlname="
2716 if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
2718 errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
2721 #undef STR_OLD_LIBRARY
2722 #define STR_OLD_LIBRARY "old_library="
2723 else if (strncmp (line, STR_OLD_LIBRARY,
2724 sizeof (STR_OLD_LIBRARY) - 1) == 0)
2726 errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
2729 #define STR_LIBDIR "libdir="
2730 else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
2732 errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);
2735 #undef STR_DL_DEPLIBS
2736 #define STR_DL_DEPLIBS "dependency_libs="
2737 else if (strncmp (line, STR_DL_DEPLIBS,
2738 sizeof (STR_DL_DEPLIBS) - 1) == 0)
2740 errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
2742 else if (strcmp (line, "installed=yes\n") == 0)
2746 else if (strcmp (line, "installed=no\n") == 0)
2751 #undef STR_LIBRARY_NAMES
2752 #define STR_LIBRARY_NAMES "library_names="
2753 else if (! dlname && strncmp (line, STR_LIBRARY_NAMES,
2754 sizeof (STR_LIBRARY_NAMES) - 1) == 0)
2757 errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
2760 && (last_libname = strrchr (dlname, ' ')) != 0)
2762 last_libname = lt_estrdup (last_libname + 1);
2768 LT_DLMEM_REASSIGN (dlname, last_libname);
2779 /* allocate the handle */
2780 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
2786 free_vars (dlname, old_name, libdir, deplibs);
2787 LT_DLFREE (*phandle);
2793 memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
2794 if (load_deplibs (*phandle, deplibs) == 0)
2796 newhandle = *phandle;
2797 /* find_module may replace newhandle */
2798 if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
2800 unload_deplibs (*phandle);
2809 free_vars (dlname, old_name, libdir, deplibs);
2812 LT_DLFREE (*phandle);
2816 if (*phandle != newhandle)
2818 unload_deplibs (*phandle);
2823 /* not a libtool module */
2824 *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
2831 memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
2832 newhandle = *phandle;
2834 /* If the module has no directory name component, try to find it
2835 first in user_search_path and then other prescribed paths.
2836 Otherwise (or in any case if the module was not yet found) try
2837 opening just the module name as passed. */
2838 if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
2839 && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
2841 #ifdef LTDL_SHLIBPATH_VAR
2842 && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
2845 #ifdef LTDL_SYSSEARCHPATH
2846 && !find_handle (sys_search_path, base_name, &newhandle)
2850 tryall_dlopen (&newhandle, filename);
2855 LT_DLFREE (*phandle);
2862 LT_DLMEM_REASSIGN (*phandle, newhandle);
2864 if ((*phandle)->info.ref_count == 0)
2866 (*phandle)->info.ref_count = 1;
2867 LT_DLMEM_REASSIGN ((*phandle)->info.name, name);
2870 (*phandle)->next = handles;
2872 LT_DLMUTEX_UNLOCK ();
2875 LT_DLMUTEX_SETERROR (saved_error);
2880 LT_DLFREE (canonical);
2886 lt_dlopen (filename)
2887 const char *filename;
2889 lt_dlhandle handle = 0;
2891 /* Just incase we missed a code path in try_dlopen() that reports
2892 an error, but forgets to reset handle... */
2893 if (try_dlopen (&handle, filename) != 0)
2899 /* If the last error messge store was `FILE_NOT_FOUND', then return
2904 const char *error = 0;
2906 LT_DLMUTEX_GETERROR (error);
2907 if (error == LT_DLSTRERROR (FILE_NOT_FOUND))
2913 /* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
2914 open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
2915 and if a file is still not found try again with SHLIB_EXT appended
2918 lt_dlopenext (filename)
2919 const char *filename;
2921 lt_dlhandle handle = 0;
2926 int file_found = 1; /* until proven otherwise */
2930 return lt_dlopen (filename);
2935 len = LT_STRLEN (filename);
2936 ext = strrchr (filename, '.');
2938 /* If FILENAME already bears a suitable extension, there is no need
2939 to try appending additional extensions. */
2940 if (ext && ((strcmp (ext, archive_ext) == 0)
2941 #ifdef LTDL_SHLIB_EXT
2942 || (strcmp (ext, shlib_ext) == 0)
2946 return lt_dlopen (filename);
2949 /* First try appending ARCHIVE_EXT. */
2950 tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1);
2954 strcpy (tmp, filename);
2955 strcat (tmp, archive_ext);
2956 errors = try_dlopen (&handle, tmp);
2958 /* If we found FILENAME, stop searching -- whether we were able to
2959 load the file as a module or not. If the file exists but loading
2960 failed, it is better to return an error message here than to
2961 report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
2962 in the module search path. */
2963 if (handle || ((errors > 0) && !file_not_found ()))
2969 #ifdef LTDL_SHLIB_EXT
2970 /* Try appending SHLIB_EXT. */
2971 if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
2974 tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
2978 strcpy (tmp, filename);
2982 tmp[len] = LT_EOS_CHAR;
2985 strcat(tmp, shlib_ext);
2986 errors = try_dlopen (&handle, tmp);
2988 /* As before, if the file was found but loading failed, return now
2989 with the current error message. */
2990 if (handle || ((errors > 0) && file_not_found ()))
2997 /* Still here? Then we really did fail to locate any of the file
2999 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
3006 lt_argz_insert (pargz, pargz_len, before, entry)
3014 if ((error = argz_insert (pargz, pargz_len, before, entry)))
3019 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
3022 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
3032 lt_argz_insertinorder (pargz, pargz_len, entry)
3041 assert (entry && *entry);
3044 while ((before = argz_next (*pargz, *pargz_len, before)))
3046 int cmp = strcmp (entry, before);
3049 if (cmp == 0) return 0; /* No duplicates! */
3052 return lt_argz_insert (pargz, pargz_len, before, entry);
3056 lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
3065 size_t end_offset = 0;
3073 dir_len = LT_STRLEN (dirnam);
3074 end = dp->d_name + LT_D_NAMLEN(dp);
3076 /* Ignore version numbers. */
3079 for (p = end; p -1 > dp->d_name; --p)
3080 if (strchr (".0123456789", p[-1]) == 0)
3087 /* Ignore filename extension. */
3090 for (p = end -1; p > dp->d_name; --p)
3098 /* Prepend the directory name. */
3099 end_offset = end - dp->d_name;
3100 buf_len = dir_len + 1+ end_offset;
3101 buf = LT_EMALLOC (char, 1+ buf_len);
3107 strcpy (buf, dirnam);
3109 strncat (buf, dp->d_name, end_offset);
3110 buf[buf_len] = LT_EOS_CHAR;
3112 /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
3113 if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
3122 list_files_by_dir (dirnam, pargz, pargz_len)
3130 assert (dirnam && *dirnam);
3133 assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
3135 dirp = opendir (dirnam);
3138 struct dirent *dp = 0;
3140 while ((dp = readdir (dirp)))
3141 if (dp->d_name[0] != '.')
3142 if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
3157 /* If there are any files in DIRNAME, call the function passed in
3158 DATA1 (with the name of each file and DATA2 as arguments). */
3160 foreachfile_callback (dirname, data1, data2)
3165 int (*func) LT_PARAMS((const char *filename, lt_ptr data))
3166 = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
3170 size_t argz_len = 0;
3172 if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
3179 while ((filename = argz_next (argz, argz_len, filename)))
3180 if ((is_done = (*func) (filename, data2)))
3191 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
3192 with DATA. The filenames passed to FUNC would be suitable for
3193 passing to lt_dlopenext. The extensions are stripped so that
3194 individual modules do not generate several entries (e.g. libfoo.la,
3195 libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
3196 then the same directories that lt_dlopen would search are examined. */
3198 lt_dlforeachfile (search_path, func, data)
3199 const char *search_path;
3200 int (*func) LT_PARAMS ((const char *filename, lt_ptr data));
3207 /* If a specific path was passed, search only the directories
3209 is_done = foreach_dirinpath (search_path, 0,
3210 foreachfile_callback, func, data);
3214 /* Otherwise search the default paths. */
3215 is_done = foreach_dirinpath (user_search_path, 0,
3216 foreachfile_callback, func, data);
3219 is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
3220 foreachfile_callback, func, data);
3223 #ifdef LTDL_SHLIBPATH_VAR
3226 is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0,
3227 foreachfile_callback, func, data);
3230 #ifdef LTDL_SYSSEARCHPATH
3233 is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0,
3234 foreachfile_callback, func, data);
3246 lt_dlhandle cur, last;
3251 /* check whether the handle is valid */
3252 last = cur = handles;
3253 while (cur && handle != cur)
3261 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3266 handle->info.ref_count--;
3268 /* Note that even with resident modules, we must track the ref_count
3269 correctly incase the user decides to reset the residency flag
3270 later (even though the API makes no provision for that at the
3272 if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle))
3274 lt_user_data data = handle->loader->dlloader_data;
3276 if (handle != handles)
3278 last->next = handle->next;
3282 handles = handle->next;
3285 errors += handle->loader->module_close (data, handle->module);
3286 errors += unload_deplibs(handle);
3288 LT_DLFREE (handle->info.filename);
3289 LT_DLFREE (handle->info.name);
3295 if (LT_DLIS_RESIDENT (handle))
3297 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
3302 LT_DLMUTEX_UNLOCK ();
3308 lt_dlsym (handle, symbol)
3313 char lsym[LT_SYMBOL_LENGTH];
3320 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3326 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
3330 lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
3331 + LT_STRLEN (handle->info.name);
3333 if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
3339 sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
3342 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
3347 data = handle->loader->dlloader_data;
3348 if (handle->info.name)
3350 const char *saved_error;
3352 LT_DLMUTEX_GETERROR (saved_error);
3354 /* this is a libtool module */
3355 if (handle->loader->sym_prefix)
3357 strcpy(sym, handle->loader->sym_prefix);
3358 strcat(sym, handle->info.name);
3362 strcpy(sym, handle->info.name);
3365 strcat(sym, "_LTX_");
3366 strcat(sym, symbol);
3368 /* try "modulename_LTX_symbol" */
3369 address = handle->loader->find_sym (data, handle->module, sym);
3378 LT_DLMUTEX_SETERROR (saved_error);
3381 /* otherwise try "symbol" */
3382 if (handle->loader->sym_prefix)
3384 strcpy(sym, handle->loader->sym_prefix);
3385 strcat(sym, symbol);
3389 strcpy(sym, symbol);
3392 address = handle->loader->find_sym (data, handle->module, sym);
3406 LT_DLMUTEX_GETERROR (error);
3407 LT_DLMUTEX_SETERROR (0);
3409 return error ? error : LT_DLSTRERROR (UNKNOWN);
3413 lt_dlpath_insertdir (ppath, before, dir)
3419 char *canonical = 0;
3421 size_t argz_len = 0;
3424 assert (dir && *dir);
3426 if (canonicalize_path (dir, &canonical) != 0)
3432 assert (canonical && *canonical);
3434 /* If *PPATH is empty, set it to DIR. */
3437 assert (!before); /* BEFORE cannot be set without PPATH. */
3438 assert (dir); /* Without DIR, don't call this function! */
3440 *ppath = lt_estrdup (dir);
3447 assert (ppath && *ppath);
3449 if (argzize_path (*ppath, &argz, &argz_len) != 0)
3455 /* Convert BEFORE into an equivalent offset into ARGZ. This only works
3456 if *PPATH is already canonicalized, and hence does not change length
3457 with respect to ARGZ. We canonicalize each entry as it is added to
3458 the search path, and don't call this function with (uncanonicalized)
3459 user paths, so this is a fair assumption. */
3462 assert (*ppath <= before);
3463 assert (before - *ppath <= strlen (*ppath));
3465 before = before - *ppath + argz;
3468 if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
3474 argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
3475 LT_DLMEM_REASSIGN (*ppath, argz);
3478 LT_DLFREE (canonical);
3485 lt_dladdsearchdir (search_dir)
3486 const char *search_dir;
3490 if (search_dir && *search_dir)
3493 if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
3495 LT_DLMUTEX_UNLOCK ();
3502 lt_dlinsertsearchdir (before, search_dir)
3504 const char *search_dir;
3511 if ((before < user_search_path)
3512 || (before >= user_search_path + LT_STRLEN (user_search_path)))
3514 LT_DLMUTEX_UNLOCK ();
3515 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
3518 LT_DLMUTEX_UNLOCK ();
3521 if (search_dir && *search_dir)
3524 if (lt_dlpath_insertdir (&user_search_path,
3525 (char *) before, search_dir) != 0)
3529 LT_DLMUTEX_UNLOCK ();
3536 lt_dlsetsearchpath (search_path)
3537 const char *search_path;
3542 LT_DLFREE (user_search_path);
3543 LT_DLMUTEX_UNLOCK ();
3545 if (!search_path || !LT_STRLEN (search_path))
3551 if (canonicalize_path (search_path, &user_search_path) != 0)
3553 LT_DLMUTEX_UNLOCK ();
3559 lt_dlgetsearchpath ()
3561 const char *saved_path;
3564 saved_path = user_search_path;
3565 LT_DLMUTEX_UNLOCK ();
3571 lt_dlmakeresident (handle)
3578 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3583 LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
3590 lt_dlisresident (handle)
3595 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3599 return LT_DLIS_RESIDENT (handle);
3605 /* --- MODULE INFORMATION --- */
3608 lt_dlgetinfo (handle)
3613 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3617 return &(handle->info);
3621 lt_dlhandle_next (place)
3624 return place ? place->next : handles;
3628 lt_dlforeach (func, data)
3629 int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data));
3640 lt_dlhandle tmp = cur;
3643 if ((*func) (tmp, data))
3650 LT_DLMUTEX_UNLOCK ();
3656 lt_dlcaller_register ()
3658 static lt_dlcaller_id last_caller_id = 0;
3662 result = ++last_caller_id;
3663 LT_DLMUTEX_UNLOCK ();
3669 lt_dlcaller_set_data (key, handle, data)
3675 lt_ptr stale = (lt_ptr) 0;
3678 /* This needs to be locked so that the caller data can be updated
3679 simultaneously by different threads. */
3682 if (handle->caller_data)
3683 while (handle->caller_data[n_elements].key)
3686 for (i = 0; i < n_elements; ++i)
3688 if (handle->caller_data[i].key == key)
3690 stale = handle->caller_data[i].data;
3695 /* Ensure that there is enough room in this handle's caller_data
3696 array to accept a new element (and an empty end marker). */
3697 if (i == n_elements)
3699 lt_caller_data *temp
3700 = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements);
3708 handle->caller_data = temp;
3710 /* We only need this if we needed to allocate a new caller_data. */
3711 handle->caller_data[i].key = key;
3712 handle->caller_data[1+ i].key = 0;
3715 handle->caller_data[i].data = data;
3718 LT_DLMUTEX_UNLOCK ();
3724 lt_dlcaller_get_data (key, handle)
3728 lt_ptr result = (lt_ptr) 0;
3730 /* This needs to be locked so that the caller data isn't updated by
3731 another thread part way through this function. */
3734 /* Locate the index of the element with a matching KEY. */
3737 for (i = 0; handle->caller_data[i].key; ++i)
3739 if (handle->caller_data[i].key == key)
3741 result = handle->caller_data[i].data;
3747 LT_DLMUTEX_UNLOCK ();
3754 /* --- USER MODULE LOADER API --- */
3758 lt_dlloader_add (place, dlloader, loader_name)
3760 const struct lt_user_dlloader *dlloader;
3761 const char *loader_name;
3764 lt_dlloader *node = 0, *ptr = 0;
3766 if ((dlloader == 0) /* diagnose null parameters */
3767 || (dlloader->module_open == 0)
3768 || (dlloader->module_close == 0)
3769 || (dlloader->find_sym == 0))
3771 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
3775 /* Create a new dlloader node with copies of the user callbacks. */
3776 node = LT_EMALLOC (lt_dlloader, 1);
3781 node->loader_name = loader_name;
3782 node->sym_prefix = dlloader->sym_prefix;
3783 node->dlloader_exit = dlloader->dlloader_exit;
3784 node->module_open = dlloader->module_open;
3785 node->module_close = dlloader->module_close;
3786 node->find_sym = dlloader->find_sym;
3787 node->dlloader_data = dlloader->dlloader_data;
3792 /* If there are no loaders, NODE becomes the list! */
3797 /* If PLACE is not set, add NODE to the end of the
3799 for (ptr = loaders; ptr->next; ptr = ptr->next)
3806 else if (loaders == place)
3808 /* If PLACE is the first loader, NODE goes first. */
3814 /* Find the node immediately preceding PLACE. */
3815 for (ptr = loaders; ptr->next != place; ptr = ptr->next)
3820 if (ptr->next != place)
3822 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
3827 /* Insert NODE between PTR and PLACE. */
3833 LT_DLMUTEX_UNLOCK ();
3839 lt_dlloader_remove (loader_name)
3840 const char *loader_name;
3842 lt_dlloader *place = lt_dlloader_find (loader_name);
3848 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
3854 /* Fail if there are any open modules which use this loader. */
3855 for (handle = handles; handle; handle = handle->next)
3857 if (handle->loader == place)
3859 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
3865 if (place == loaders)
3867 /* PLACE is the first loader in the list. */
3868 loaders = loaders->next;
3872 /* Find the loader before the one being removed. */
3874 for (prev = loaders; prev->next; prev = prev->next)
3876 if (!strcmp (prev->next->loader_name, loader_name))
3883 prev->next = prev->next->next;
3886 if (place->dlloader_exit)
3888 errors = place->dlloader_exit (place->dlloader_data);
3894 LT_DLMUTEX_UNLOCK ();
3900 lt_dlloader_next (place)
3906 next = place ? place->next : loaders;
3907 LT_DLMUTEX_UNLOCK ();
3913 lt_dlloader_name (place)
3916 const char *name = 0;
3921 name = place ? place->loader_name : 0;
3922 LT_DLMUTEX_UNLOCK ();
3926 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
3933 lt_dlloader_data (place)
3936 lt_user_data *data = 0;
3941 data = place ? &(place->dlloader_data) : 0;
3942 LT_DLMUTEX_UNLOCK ();
3946 LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
3953 lt_dlloader_find (loader_name)
3954 const char *loader_name;
3956 lt_dlloader *place = 0;
3959 for (place = loaders; place; place = place->next)
3961 if (strcmp (place->loader_name, loader_name) == 0)
3966 LT_DLMUTEX_UNLOCK ();