Code

Imported Upstream version 5.5.0
[pkg-collectd.git] / libltdl / ltdl.c
1 /* ltdl.c -- system independent dlopen wrapper
3    Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006,
4                  2007, 2008, 2011 Free Software Foundation, Inc.
5    Written by Thomas Tanner, 1998
7    NOTE: The canonical source of this file is maintained with the
8    GNU Libtool package.  Report bugs to bug-libtool@gnu.org.
10 GNU Libltdl is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
15 As a special exception to the GNU Lesser General Public License,
16 if you distribute this file as part of a program or library that
17 is built using GNU Libtool, you may include this file under the
18 same distribution terms that you use for the rest of that program.
20 GNU Libltdl is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 GNU Lesser General Public License for more details.
25 You should have received a copy of the GNU Lesser General Public
26 License along with GNU Libltdl; see the file COPYING.LIB.  If not, a
27 copy can be downloaded from  http://www.gnu.org/licenses/lgpl.html,
28 or obtained by writing to the Free Software Foundation, Inc.,
29 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 */
32 #include "lt__private.h"
33 #include "lt_system.h"
34 #include "lt_dlloader.h"
37 /* --- MANIFEST CONSTANTS --- */
40 /* Standard libltdl search path environment variable name  */
41 #undef  LTDL_SEARCHPATH_VAR
42 #define LTDL_SEARCHPATH_VAR     "LTDL_LIBRARY_PATH"
44 /* Standard libtool archive file extension.  */
45 #undef  LT_ARCHIVE_EXT
46 #define LT_ARCHIVE_EXT  ".la"
48 /* max. filename length */
49 #if !defined(LT_FILENAME_MAX)
50 #  define LT_FILENAME_MAX       1024
51 #endif
53 #if !defined(LT_LIBEXT)
54 #  define LT_LIBEXT "a"
55 #endif
57 #if !defined(LT_LIBPREFIX)
58 #  define LT_LIBPREFIX "lib"
59 #endif
61 /* This is the maximum symbol size that won't require malloc/free */
62 #undef  LT_SYMBOL_LENGTH
63 #define LT_SYMBOL_LENGTH        128
65 /* This accounts for the _LTX_ separator */
66 #undef  LT_SYMBOL_OVERHEAD
67 #define LT_SYMBOL_OVERHEAD      5
69 /* Various boolean flags can be stored in the flags field of an
70    lt_dlhandle... */
71 #define LT_DLIS_RESIDENT(handle)  ((handle)->info.is_resident)
72 #define LT_DLIS_SYMGLOBAL(handle) ((handle)->info.is_symglobal)
73 #define LT_DLIS_SYMLOCAL(handle)  ((handle)->info.is_symlocal)
76 static  const char      objdir[]                = LT_OBJDIR;
77 static  const char      archive_ext[]           = LT_ARCHIVE_EXT;
78 static  const char      libext[]                = LT_LIBEXT;
79 static  const char      libprefix[]             = LT_LIBPREFIX;
80 #if defined(LT_MODULE_EXT)
81 static  const char      shlib_ext[]             = LT_MODULE_EXT;
82 #endif
83 /* If the loadable module suffix is not the same as the linkable
84  * shared library suffix, this will be defined. */
85 #if defined(LT_SHARED_EXT)
86 static  const char      shared_ext[]            = LT_SHARED_EXT;
87 #endif
88 #if defined(LT_DLSEARCH_PATH)
89 static  const char      sys_dlsearch_path[]     = LT_DLSEARCH_PATH;
90 #endif
94 \f
95 /* --- DYNAMIC MODULE LOADING --- */
98 /* The type of a function used at each iteration of  foreach_dirinpath().  */
99 typedef int     foreach_callback_func (char *filename, void *data1,
100                                        void *data2);
101 /* foreachfile_callback itself calls a function of this type: */
102 typedef int     file_worker_func      (const char *filename, void *data);
105 static  int     foreach_dirinpath     (const char *search_path,
106                                        const char *base_name,
107                                        foreach_callback_func *func,
108                                        void *data1, void *data2);
109 static  int     find_file_callback    (char *filename, void *data1,
110                                        void *data2);
111 static  int     find_handle_callback  (char *filename, void *data,
112                                        void *ignored);
113 static  int     foreachfile_callback  (char *filename, void *data1,
114                                        void *data2);
117 static  int     canonicalize_path     (const char *path, char **pcanonical);
118 static  int     argzize_path          (const char *path,
119                                        char **pargz, size_t *pargz_len);
120 static  FILE   *find_file             (const char *search_path,
121                                        const char *base_name, char **pdir);
122 static  lt_dlhandle *find_handle      (const char *search_path,
123                                        const char *base_name,
124                                        lt_dlhandle *handle,
125                                        lt_dladvise advise);
126 static  int     find_module           (lt_dlhandle *handle, const char *dir,
127                                        const char *libdir, const char *dlname,
128                                        const char *old_name, int installed,
129                                        lt_dladvise advise);
130 static  int     has_library_ext       (const char *filename);
131 static  int     load_deplibs          (lt_dlhandle handle,  char *deplibs);
132 static  int     trim                  (char **dest, const char *str);
133 static  int     try_dlopen            (lt_dlhandle *handle,
134                                        const char *filename, const char *ext,
135                                        lt_dladvise advise);
136 static  int     tryall_dlopen         (lt_dlhandle *handle,
137                                        const char *filename,
138                                        lt_dladvise padvise,
139                                        const lt_dlvtable *vtable);
140 static  int     unload_deplibs        (lt_dlhandle handle);
141 static  int     lt_argz_insert        (char **pargz, size_t *pargz_len,
142                                        char *before, const char *entry);
143 static  int     lt_argz_insertinorder (char **pargz, size_t *pargz_len,
144                                        const char *entry);
145 static  int     lt_argz_insertdir     (char **pargz, size_t *pargz_len,
146                                        const char *dirnam, struct dirent *dp);
147 static  int     lt_dlpath_insertdir   (char **ppath, char *before,
148                                        const char *dir);
149 static  int     list_files_by_dir     (const char *dirnam,
150                                        char **pargz, size_t *pargz_len);
151 static  int     file_not_found        (void);
153 #ifdef HAVE_LIBDLLOADER
154 static  int     loader_init_callback  (lt_dlhandle handle);
155 #endif /* HAVE_LIBDLLOADER */
157 static  int     loader_init           (lt_get_vtable *vtable_func,
158                                        lt_user_data data);
160 static  char           *user_search_path= 0;
161 static  lt_dlhandle     handles = 0;
162 static  int             initialized     = 0;
164 /* Our memory failure callback sets the error message to be passed back
165    up to the client, so we must be careful to return from mallocation
166    callers if allocation fails (as this callback returns!!).  */
167 void
168 lt__alloc_die_callback (void)
170   LT__SETERROR (NO_MEMORY);
173 #ifdef HAVE_LIBDLLOADER
174 /* This function is called to initialise each preloaded module loader,
175    and hook it into the list of loaders to be used when attempting to
176    dlopen an application module.  */
177 static int
178 loader_init_callback (lt_dlhandle handle)
180   lt_get_vtable *vtable_func = (lt_get_vtable *) lt_dlsym (handle, "get_vtable");
181   return loader_init (vtable_func, 0);
183 #endif /* HAVE_LIBDLLOADER */
185 static int
186 loader_init (lt_get_vtable *vtable_func, lt_user_data data)
188   const lt_dlvtable *vtable = 0;
189   int errors = 0;
191   if (vtable_func)
192     {
193       vtable = (*vtable_func) (data);
194     }
196   /* lt_dlloader_add will LT__SETERROR if it fails.  */
197   errors += lt_dlloader_add (vtable);
199   assert (errors || vtable);
201   if ((!errors) && vtable->dlloader_init)
202     {
203       if ((*vtable->dlloader_init) (vtable->dlloader_data))
204         {
205           LT__SETERROR (INIT_LOADER);
206           ++errors;
207         }
208     }
210   return errors;
213 /* Bootstrap the loader loading with the preopening loader.  */
214 #define get_vtable              preopen_LTX_get_vtable
215 #define preloaded_symbols       LT_CONC3(lt_, LTDLOPEN, _LTX_preloaded_symbols)
217 LT_BEGIN_C_DECLS
218 LT_SCOPE const lt_dlvtable *    get_vtable (lt_user_data data);
219 LT_END_C_DECLS
220 #ifdef HAVE_LIBDLLOADER
221 extern LT_DLSYM_CONST lt_dlsymlist preloaded_symbols[];
222 #endif
224 /* Initialize libltdl. */
225 int
226 lt_dlinit (void)
228   int   errors  = 0;
230   /* Initialize only at first call. */
231   if (++initialized == 1)
232     {
233       lt__alloc_die     = lt__alloc_die_callback;
234       handles           = 0;
235       user_search_path  = 0; /* empty search path */
237       /* First set up the statically loaded preload module loader, so
238          we can use it to preopen the other loaders we linked in at
239          compile time.  */
240       errors += loader_init (get_vtable, 0);
242       /* Now open all the preloaded module loaders, so the application
243          can use _them_ to lt_dlopen its own modules.  */
244 #ifdef HAVE_LIBDLLOADER
245       if (!errors)
246         {
247           errors += lt_dlpreload (preloaded_symbols);
248         }
250       if (!errors)
251         {
252           errors += lt_dlpreload_open (LT_STR(LTDLOPEN), loader_init_callback);
253         }
254 #endif /* HAVE_LIBDLLOADER */
255     }
257 #ifdef LT_DEBUG_LOADERS
258   lt_dlloader_dump();
259 #endif
261   return errors;
264 int
265 lt_dlexit (void)
267   /* shut down libltdl */
268   lt_dlloader *loader   = 0;
269   lt_dlhandle  handle   = handles;
270   int          errors   = 0;
272   if (!initialized)
273     {
274       LT__SETERROR (SHUTDOWN);
275       ++errors;
276       goto done;
277     }
279   /* shut down only at last call. */
280   if (--initialized == 0)
281     {
282       int       level;
284       while (handles && LT_DLIS_RESIDENT (handles))
285         {
286           handles = handles->next;
287         }
289       /* close all modules */
290       for (level = 1; handle; ++level)
291         {
292           lt_dlhandle cur = handles;
293           int saw_nonresident = 0;
295           while (cur)
296             {
297               lt_dlhandle tmp = cur;
298               cur = cur->next;
299               if (!LT_DLIS_RESIDENT (tmp))
300                 {
301                   saw_nonresident = 1;
302                   if (tmp->info.ref_count <= level)
303                     {
304                       if (lt_dlclose (tmp))
305                         {
306                           ++errors;
307                         }
308                       /* Make sure that the handle pointed to by 'cur' still exists.
309                          lt_dlclose recursively closes dependent libraries which removes
310                          them from the linked list.  One of these might be the one
311                          pointed to by 'cur'.  */
312                       if (cur)
313                         {
314                           for (tmp = handles; tmp; tmp = tmp->next)
315                             if (tmp == cur)
316                               break;
317                           if (! tmp)
318                             cur = handles;
319                         }
320                     }
321                 }
322             }
323           /* done if only resident modules are left */
324           if (!saw_nonresident)
325             break;
326         }
328       /* When removing loaders, we can only find out failure by testing
329          the error string, so avoid a spurious one from an earlier
330          failed command. */
331       if (!errors)
332         LT__SETERRORSTR (0);
334       /* close all loaders */
335       for (loader = (lt_dlloader *) lt_dlloader_next (NULL); loader;)
336         {
337           lt_dlloader *next   = (lt_dlloader *) lt_dlloader_next (loader);
338           lt_dlvtable *vtable = (lt_dlvtable *) lt_dlloader_get (loader);
340           if ((vtable = lt_dlloader_remove ((char *) vtable->name)))
341             {
342               FREE (vtable);
343             }
344           else
345             {
346               /* ignore errors due to resident modules */
347               const char *err;
348               LT__GETERROR (err);
349               if (err)
350                 ++errors;
351             }
353           loader = next;
354         }
356       FREE(user_search_path);
357     }
359  done:
360   return errors;
364 /* Try VTABLE or, if VTABLE is NULL, all available loaders for FILENAME.
365    If the library is not successfully loaded, return non-zero.  Otherwise,
366    the dlhandle is stored at the address given in PHANDLE.  */
367 static int
368 tryall_dlopen (lt_dlhandle *phandle, const char *filename,
369                lt_dladvise advise, const lt_dlvtable *vtable)
371   lt_dlhandle   handle          = handles;
372   const char *  saved_error     = 0;
373   int           errors          = 0;
375 #ifdef LT_DEBUG_LOADERS
376   fprintf (stderr, "tryall_dlopen (%s, %s)\n",
377            filename ? filename : "(null)",
378            vtable ? vtable->name : "(ALL)");
379 #endif
381   LT__GETERROR (saved_error);
383   /* check whether the module was already opened */
384   for (;handle; handle = handle->next)
385     {
386       if ((handle->info.filename == filename) /* dlopen self: 0 == 0 */
387           || (handle->info.filename && filename
388               && streq (handle->info.filename, filename)))
389         {
390           break;
391         }
392     }
394   if (handle)
395     {
396       ++handle->info.ref_count;
397       *phandle = handle;
398       goto done;
399     }
401   handle = *phandle;
402   if (filename)
403     {
404       /* Comment out the check of file permissions using access.
405          This call seems to always return -1 with error EACCES.
406       */
407       /* We need to catch missing file errors early so that
408          file_not_found() can detect what happened.
409       if (access (filename, R_OK) != 0)
410         {
411           LT__SETERROR (FILE_NOT_FOUND);
412           ++errors;
413           goto done;
414         } */
416       handle->info.filename = lt__strdup (filename);
417       if (!handle->info.filename)
418         {
419           ++errors;
420           goto done;
421         }
422     }
423   else
424     {
425       handle->info.filename = 0;
426     }
428   {
429     lt_dlloader loader = lt_dlloader_next (0);
430     const lt_dlvtable *loader_vtable;
432     do
433       {
434         if (vtable)
435           loader_vtable = vtable;
436         else
437           loader_vtable = lt_dlloader_get (loader);
439 #ifdef LT_DEBUG_LOADERS
440         fprintf (stderr, "Calling %s->module_open (%s)\n",
441                  (loader_vtable && loader_vtable->name) ? loader_vtable->name : "(null)",
442                  filename ? filename : "(null)");
443 #endif
444         handle->module = (*loader_vtable->module_open) (loader_vtable->dlloader_data,
445                                                         filename, advise);
446 #ifdef LT_DEBUG_LOADERS
447         fprintf (stderr, "  Result: %s\n",
448                  handle->module ? "Success" : "Failed");
449 #endif
451         if (handle->module != 0)
452           {
453             if (advise)
454               {
455                 handle->info.is_resident  = advise->is_resident;
456                 handle->info.is_symglobal = advise->is_symglobal;
457                 handle->info.is_symlocal  = advise->is_symlocal;
458               }
459             break;
460           }
461       }
462     while (!vtable && (loader = lt_dlloader_next (loader)));
464     /* If VTABLE was given but couldn't open the module, or VTABLE wasn't
465        given but we exhausted all loaders without opening the module, bail
466        out!  */
467     if ((vtable && !handle->module)
468         || (!vtable && !loader))
469       {
470         FREE (handle->info.filename);
471         ++errors;
472         goto done;
473       }
475     handle->vtable = loader_vtable;
476   }
478   LT__SETERRORSTR (saved_error);
480  done:
481   return errors;
485 static int
486 tryall_dlopen_module (lt_dlhandle *handle, const char *prefix,
487                       const char *dirname, const char *dlname,
488                       lt_dladvise advise)
490   int      error        = 0;
491   char     *filename    = 0;
492   size_t   filename_len = 0;
493   size_t   dirname_len  = LT_STRLEN (dirname);
495   assert (handle);
496   assert (dirname);
497   assert (dlname);
498 #if defined(LT_DIRSEP_CHAR)
499   /* Only canonicalized names (i.e. with DIRSEP chars already converted)
500      should make it into this function:  */
501   assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
502 #endif
504   if (dirname_len > 0)
505     if (dirname[dirname_len -1] == '/')
506       --dirname_len;
507   filename_len = dirname_len + 1 + LT_STRLEN (dlname);
509   /* Allocate memory, and combine DIRNAME and MODULENAME into it.
510      The PREFIX (if any) is handled below.  */
511   filename  = MALLOC (char, filename_len + 1);
512   if (!filename)
513     return 1;
515   sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
517   /* Now that we have combined DIRNAME and MODULENAME, if there is
518      also a PREFIX to contend with, simply recurse with the arguments
519      shuffled.  Otherwise, attempt to open FILENAME as a module.  */
520   if (prefix)
521     {
522       error += tryall_dlopen_module (handle, (const char *) 0,
523                                      prefix, filename, advise);
524     }
525   else if (tryall_dlopen (handle, filename, advise, 0) != 0)
526     {
527       ++error;
528     }
530   FREE (filename);
531   return error;
534 static int
535 find_module (lt_dlhandle *handle, const char *dir, const char *libdir,
536              const char *dlname,  const char *old_name, int installed,
537              lt_dladvise advise)
539   /* Try to open the old library first; if it was dlpreopened,
540      we want the preopened version of it, even if a dlopenable
541      module is available.  */
542   if (old_name && tryall_dlopen (handle, old_name,
543                           advise, lt_dlloader_find ("lt_preopen") ) == 0)
544     {
545       return 0;
546     }
548   /* Try to open the dynamic library.  */
549   if (dlname)
550     {
551       /* try to open the installed module */
552       if (installed && libdir)
553         {
554           if (tryall_dlopen_module (handle, (const char *) 0,
555                                     libdir, dlname, advise) == 0)
556             return 0;
557         }
559       /* try to open the not-installed module */
560       if (!installed)
561         {
562           if (tryall_dlopen_module (handle, dir, objdir,
563                                     dlname, advise) == 0)
564             return 0;
565         }
567       /* maybe it was moved to another directory */
568       {
569           if (dir && (tryall_dlopen_module (handle, (const char *) 0,
570                                             dir, dlname, advise) == 0))
571             return 0;
572       }
573     }
575   return 1;
579 static int
580 canonicalize_path (const char *path, char **pcanonical)
582   char *canonical = 0;
584   assert (path && *path);
585   assert (pcanonical);
587   canonical = MALLOC (char, 1+ LT_STRLEN (path));
588   if (!canonical)
589     return 1;
591   {
592     size_t dest = 0;
593     size_t src;
594     for (src = 0; path[src] != LT_EOS_CHAR; ++src)
595       {
596         /* Path separators are not copied to the beginning or end of
597            the destination, or if another separator would follow
598            immediately.  */
599         if (path[src] == LT_PATHSEP_CHAR)
600           {
601             if ((dest == 0)
602                 || (path[1+ src] == LT_PATHSEP_CHAR)
603                 || (path[1+ src] == LT_EOS_CHAR))
604               continue;
605           }
607         /* Anything other than a directory separator is copied verbatim.  */
608         if ((path[src] != '/')
609 #if defined(LT_DIRSEP_CHAR)
610             && (path[src] != LT_DIRSEP_CHAR)
611 #endif
612             )
613           {
614             canonical[dest++] = path[src];
615           }
616         /* Directory separators are converted and copied only if they are
617            not at the end of a path -- i.e. before a path separator or
618            NULL terminator.  */
619         else if ((path[1+ src] != LT_PATHSEP_CHAR)
620                  && (path[1+ src] != LT_EOS_CHAR)
621 #if defined(LT_DIRSEP_CHAR)
622                  && (path[1+ src] != LT_DIRSEP_CHAR)
623 #endif
624                  && (path[1+ src] != '/'))
625           {
626             canonical[dest++] = '/';
627           }
628       }
630     /* Add an end-of-string marker at the end.  */
631     canonical[dest] = LT_EOS_CHAR;
632   }
634   /* Assign new value.  */
635   *pcanonical = canonical;
637   return 0;
640 static int
641 argzize_path (const char *path, char **pargz, size_t *pargz_len)
643   error_t error;
645   assert (path);
646   assert (pargz);
647   assert (pargz_len);
649   if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
650     {
651       switch (error)
652         {
653         case ENOMEM:
654           LT__SETERROR (NO_MEMORY);
655           break;
656         default:
657           LT__SETERROR (UNKNOWN);
658           break;
659         }
661       return 1;
662     }
664   return 0;
667 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
668    of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
669    non-zero or all elements are exhausted.  If BASE_NAME is non-NULL,
670    it is appended to each SEARCH_PATH element before FUNC is called.  */
671 static int
672 foreach_dirinpath (const char *search_path, const char *base_name,
673                    foreach_callback_func *func, void *data1, void *data2)
675   int    result         = 0;
676   size_t filenamesize   = 0;
677   size_t lenbase        = LT_STRLEN (base_name);
678   size_t argz_len       = 0;
679   char *argz            = 0;
680   char *filename        = 0;
681   char *canonical       = 0;
683   if (!search_path || !*search_path)
684     {
685       LT__SETERROR (FILE_NOT_FOUND);
686       goto cleanup;
687     }
689   if (canonicalize_path (search_path, &canonical) != 0)
690     goto cleanup;
692   if (argzize_path (canonical, &argz, &argz_len) != 0)
693     goto cleanup;
695   {
696     char *dir_name = 0;
697     while ((dir_name = argz_next (argz, argz_len, dir_name)))
698       {
699         size_t lendir = LT_STRLEN (dir_name);
701         if (1+ lendir + lenbase >= filenamesize)
702         {
703           FREE (filename);
704           filenamesize  = 1+ lendir + 1+ lenbase; /* "/d" + '/' + "f" + '\0' */
705           filename      = MALLOC (char, filenamesize);
706           if (!filename)
707             goto cleanup;
708         }
710         assert (filenamesize > lendir);
711         strcpy (filename, dir_name);
713         if (base_name && *base_name)
714           {
715             if (filename[lendir -1] != '/')
716               filename[lendir++] = '/';
717             strcpy (filename +lendir, base_name);
718           }
720         if ((result = (*func) (filename, data1, data2)))
721           {
722             break;
723           }
724       }
725   }
727  cleanup:
728   FREE (argz);
729   FREE (canonical);
730   FREE (filename);
732   return result;
735 /* If FILEPATH can be opened, store the name of the directory component
736    in DATA1, and the opened FILE* structure address in DATA2.  Otherwise
737    DATA1 is unchanged, but DATA2 is set to a pointer to NULL.  */
738 static int
739 find_file_callback (char *filename, void *data1, void *data2)
741   char       **pdir     = (char **) data1;
742   FILE       **pfile    = (FILE **) data2;
743   int        is_done    = 0;
745   assert (filename && *filename);
746   assert (pdir);
747   assert (pfile);
749   if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
750     {
751       char *dirend = strrchr (filename, '/');
753       if (dirend > filename)
754         *dirend   = LT_EOS_CHAR;
756       FREE (*pdir);
757       *pdir   = lt__strdup (filename);
758       is_done = (*pdir == 0) ? -1 : 1;
759     }
761   return is_done;
764 static FILE *
765 find_file (const char *search_path, const char *base_name, char **pdir)
767   FILE *file = 0;
769   foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
771   return file;
774 static int
775 find_handle_callback (char *filename, void *data, void *data2)
777   lt_dlhandle  *phandle         = (lt_dlhandle *) data;
778   int           notfound        = access (filename, R_OK);
779   lt_dladvise   advise          = (lt_dladvise) data2;
781   /* Bail out if file cannot be read...  */
782   if (notfound)
783     return 0;
785   /* Try to dlopen the file, but do not continue searching in any
786      case.  */
787   if (tryall_dlopen (phandle, filename, advise, 0) != 0)
788     *phandle = 0;
790   return 1;
793 /* If HANDLE was found return it, otherwise return 0.  If HANDLE was
794    found but could not be opened, *HANDLE will be set to 0.  */
795 static lt_dlhandle *
796 find_handle (const char *search_path, const char *base_name,
797              lt_dlhandle *phandle, lt_dladvise advise)
799   if (!search_path)
800     return 0;
802   if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
803                           phandle, advise))
804     return 0;
806   return phandle;
809 #if !defined(LTDL_DLOPEN_DEPLIBS)
810 static int
811 load_deplibs (lt_dlhandle handle, char * LT__UNUSED deplibs)
813   handle->depcount = 0;
814   return 0;
817 #else /* defined(LTDL_DLOPEN_DEPLIBS) */
818 static int
819 load_deplibs (lt_dlhandle handle, char *deplibs)
821   char  *p, *save_search_path = 0;
822   int   depcount = 0;
823   int   i;
824   char  **names = 0;
825   int   errors = 0;
827   handle->depcount = 0;
829   if (!deplibs)
830     {
831       return errors;
832     }
833   ++errors;
835   if (user_search_path)
836     {
837       save_search_path = lt__strdup (user_search_path);
838       if (!save_search_path)
839         goto cleanup;
840     }
842   /* extract search paths and count deplibs */
843   p = deplibs;
844   while (*p)
845     {
846       if (!isspace ((unsigned char) *p))
847         {
848           char *end = p+1;
849           while (*end && !isspace((unsigned char) *end))
850             {
851               ++end;
852             }
854           if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
855             {
856               char save = *end;
857               *end = 0; /* set a temporary string terminator */
858               if (lt_dladdsearchdir(p+2))
859                 {
860                   goto cleanup;
861                 }
862               *end = save;
863             }
864           else
865             {
866               ++depcount;
867             }
869           p = end;
870         }
871       else
872         {
873           ++p;
874         }
875     }
878   if (!depcount)
879     {
880       errors = 0;
881       goto cleanup;
882     }
884   names = MALLOC (char *, depcount);
885   if (!names)
886     goto cleanup;
888   /* now only extract the actual deplibs */
889   depcount = 0;
890   p = deplibs;
891   while (*p)
892     {
893       if (isspace ((unsigned char) *p))
894         {
895           ++p;
896         }
897       else
898         {
899           char *end = p+1;
900           while (*end && !isspace ((unsigned char) *end))
901             {
902               ++end;
903             }
905           if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
906             {
907               char *name;
908               char save = *end;
909               *end = 0; /* set a temporary string terminator */
910               if (strncmp(p, "-l", 2) == 0)
911                 {
912                   size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
913                   name = MALLOC (char, 1+ name_len);
914                   if (name)
915                     sprintf (name, "lib%s", p+2);
916                 }
917               else
918                 name = lt__strdup(p);
920               if (!name)
921                 goto cleanup_names;
923               names[depcount++] = name;
924               *end = save;
925             }
926           p = end;
927         }
928     }
930   /* load the deplibs (in reverse order)
931      At this stage, don't worry if the deplibs do not load correctly,
932      they may already be statically linked into the loading application
933      for instance.  There will be a more enlightening error message
934      later on if the loaded module cannot resolve all of its symbols.  */
935   if (depcount)
936     {
937       lt_dlhandle cur = handle;
938       int       j = 0;
940       cur->deplibs = MALLOC (lt_dlhandle, depcount);
941       if (!cur->deplibs)
942         goto cleanup_names;
944       for (i = 0; i < depcount; ++i)
945         {
946           cur->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
947           if (cur->deplibs[j])
948             {
949               ++j;
950             }
951         }
953       cur->depcount     = j;    /* Number of successfully loaded deplibs */
954       errors            = 0;
955     }
957  cleanup_names:
958   for (i = 0; i < depcount; ++i)
959     {
960       FREE (names[i]);
961     }
963  cleanup:
964   FREE (names);
965   /* restore the old search path */
966   if (save_search_path) {
967     MEMREASSIGN (user_search_path, save_search_path);
968   }
970   return errors;
972 #endif /* defined(LTDL_DLOPEN_DEPLIBS) */
974 static int
975 unload_deplibs (lt_dlhandle handle)
977   int i;
978   int errors = 0;
979   lt_dlhandle cur = handle;
981   if (cur->depcount)
982     {
983       for (i = 0; i < cur->depcount; ++i)
984         {
985           if (!LT_DLIS_RESIDENT (cur->deplibs[i]))
986             {
987               errors += lt_dlclose (cur->deplibs[i]);
988             }
989         }
990       FREE (cur->deplibs);
991     }
993   return errors;
996 static int
997 trim (char **dest, const char *str)
999   /* remove the leading and trailing "'" from str
1000      and store the result in dest */
1001   const char *end   = strrchr (str, '\'');
1002   size_t len        = LT_STRLEN (str);
1003   char *tmp;
1005   FREE (*dest);
1007   if (!end || end == str)
1008     return 1;
1010   if (len > 3 && str[0] == '\'')
1011     {
1012       tmp = MALLOC (char, end - str);
1013       if (!tmp)
1014         return 1;
1016       memcpy(tmp, &str[1], (end - str) - 1);
1017       tmp[(end - str) - 1] = LT_EOS_CHAR;
1018       *dest = tmp;
1019     }
1020   else
1021     {
1022       *dest = 0;
1023     }
1025   return 0;
1028 /* Read the .la file FILE. */
1029 static int
1030 parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs,
1031     char **old_name, int *installed)
1033   int           errors = 0;
1034   size_t        line_len = LT_FILENAME_MAX;
1035   char *        line = MALLOC (char, line_len);
1037   if (!line)
1038     {
1039       LT__SETERROR (FILE_NOT_FOUND);
1040       return 1;
1041     }
1043   while (!feof (file))
1044     {
1045       line[line_len-2] = '\0';
1046       if (!fgets (line, (int) line_len, file))
1047         {
1048           break;
1049         }
1051       /* Handle the case where we occasionally need to read a line
1052          that is longer than the initial buffer size.
1053          Behave even if the file contains NUL bytes due to corruption. */
1054       while (line[line_len-2] != '\0' && line[line_len-2] != '\n' && !feof (file))
1055         {
1056           line = REALLOC (char, line, line_len *2);
1057           if (!line)
1058             {
1059               ++errors;
1060               goto cleanup;
1061             }
1062           line[line_len * 2 - 2] = '\0';
1063           if (!fgets (&line[line_len -1], (int) line_len +1, file))
1064             {
1065               break;
1066             }
1067           line_len *= 2;
1068         }
1070       if (line[0] == '\n' || line[0] == '#')
1071         {
1072           continue;
1073         }
1075 #undef  STR_DLNAME
1076 #define STR_DLNAME      "dlname="
1077       if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
1078         {
1079           errors += trim (dlname, &line[sizeof (STR_DLNAME) - 1]);
1080         }
1082 #undef  STR_OLD_LIBRARY
1083 #define STR_OLD_LIBRARY "old_library="
1084       else if (strncmp (line, STR_OLD_LIBRARY,
1085             sizeof (STR_OLD_LIBRARY) - 1) == 0)
1086         {
1087           errors += trim (old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
1088         }
1090       /* Windows native tools do not understand the POSIX paths we store
1091          in libdir. */
1092 #undef  STR_LIBDIR
1093 #define STR_LIBDIR      "libdir="
1094       else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
1095         {
1096           errors += trim (libdir, &line[sizeof(STR_LIBDIR) - 1]);
1097 #ifdef __WINDOWS__
1098           /* Disallow following unix-style paths on MinGW.  */
1099           if (*libdir && (**libdir == '/' || **libdir == '\\'))
1100             **libdir = '\0';
1101 #endif
1102         }
1104 #undef  STR_DL_DEPLIBS
1105 #define STR_DL_DEPLIBS  "dependency_libs="
1106       else if (strncmp (line, STR_DL_DEPLIBS,
1107             sizeof (STR_DL_DEPLIBS) - 1) == 0)
1108         {
1109           errors += trim (deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
1110         }
1111       else if (streq (line, "installed=yes\n"))
1112         {
1113           *installed = 1;
1114         }
1115       else if (streq (line, "installed=no\n"))
1116         {
1117           *installed = 0;
1118         }
1120 #undef  STR_LIBRARY_NAMES
1121 #define STR_LIBRARY_NAMES "library_names="
1122       else if (!*dlname && strncmp (line, STR_LIBRARY_NAMES,
1123             sizeof (STR_LIBRARY_NAMES) - 1) == 0)
1124         {
1125           char *last_libname;
1126           errors += trim (dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
1127           if (!errors
1128               && *dlname
1129               && (last_libname = strrchr (*dlname, ' ')) != 0)
1130             {
1131               last_libname = lt__strdup (last_libname + 1);
1132               if (!last_libname)
1133                 {
1134                   ++errors;
1135                   goto cleanup;
1136                 }
1137               MEMREASSIGN (*dlname, last_libname);
1138             }
1139         }
1141       if (errors)
1142         break;
1143     }
1144 cleanup:
1145   FREE (line);
1146   return errors;
1150 /* Try to open FILENAME as a module. */
1151 static int
1152 try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
1153             lt_dladvise advise)
1155   const char *  saved_error     = 0;
1156   char *        archive_name    = 0;
1157   char *        canonical       = 0;
1158   char *        base_name       = 0;
1159   char *        dir             = 0;
1160   char *        name            = 0;
1161   char *        attempt         = 0;
1162   int           errors          = 0;
1163   lt_dlhandle   newhandle;
1165   assert (phandle);
1166   assert (*phandle == 0);
1168 #ifdef LT_DEBUG_LOADERS
1169   fprintf (stderr, "try_dlopen (%s, %s)\n",
1170            filename ? filename : "(null)",
1171            ext ? ext : "(null)");
1172 #endif
1174   LT__GETERROR (saved_error);
1176   /* dlopen self? */
1177   if (!filename)
1178     {
1179       *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1180       if (*phandle == 0)
1181         return 1;
1183       newhandle = *phandle;
1185       /* lt_dlclose()ing yourself is very bad!  Disallow it.  */
1186       newhandle->info.is_resident = 1;
1188       if (tryall_dlopen (&newhandle, 0, advise, 0) != 0)
1189         {
1190           FREE (*phandle);
1191           return 1;
1192         }
1194       goto register_handle;
1195     }
1197   assert (filename && *filename);
1199   if (ext)
1200     {
1201       attempt = MALLOC (char, LT_STRLEN (filename) + LT_STRLEN (ext) + 1);
1202       if (!attempt)
1203         return 1;
1205       sprintf(attempt, "%s%s", filename, ext);
1206     }
1207   else
1208     {
1209       attempt = lt__strdup (filename);
1210       if (!attempt)
1211         return 1;
1212     }
1214   /* Doing this immediately allows internal functions to safely
1215      assume only canonicalized paths are passed.  */
1216   if (canonicalize_path (attempt, &canonical) != 0)
1217     {
1218       ++errors;
1219       goto cleanup;
1220     }
1222   /* If the canonical module name is a path (relative or absolute)
1223      then split it into a directory part and a name part.  */
1224   base_name = strrchr (canonical, '/');
1225   if (base_name)
1226     {
1227       size_t dirlen = (1+ base_name) - canonical;
1229       dir = MALLOC (char, 1+ dirlen);
1230       if (!dir)
1231         {
1232           ++errors;
1233           goto cleanup;
1234         }
1236       strncpy (dir, canonical, dirlen);
1237       dir[dirlen] = LT_EOS_CHAR;
1239       ++base_name;
1240     }
1241   else
1242     MEMREASSIGN (base_name, canonical);
1244   assert (base_name && *base_name);
1246   ext = strrchr (base_name, '.');
1247   if (!ext)
1248     {
1249       ext = base_name + LT_STRLEN (base_name);
1250     }
1252   /* extract the module name from the file name */
1253   name = MALLOC (char, ext - base_name + 1);
1254   if (!name)
1255     {
1256       ++errors;
1257       goto cleanup;
1258     }
1260   /* canonicalize the module name */
1261   {
1262     int i;
1263     for (i = 0; i < ext - base_name; ++i)
1264       {
1265         if (isalnum ((unsigned char)(base_name[i])))
1266           {
1267             name[i] = base_name[i];
1268           }
1269         else
1270           {
1271             name[i] = '_';
1272           }
1273       }
1274     name[ext - base_name] = LT_EOS_CHAR;
1275   }
1277   /* Before trawling through the filesystem in search of a module,
1278      check whether we are opening a preloaded module.  */
1279   if (!dir)
1280     {
1281       const lt_dlvtable *vtable = lt_dlloader_find ("lt_preopen");
1283       if (vtable)
1284         {
1285           /* libprefix + name + "." + libext + NULL */
1286           archive_name = MALLOC (char, strlen (libprefix) + LT_STRLEN (name) + strlen (libext) + 2);
1287           *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1289           if ((*phandle == NULL) || (archive_name == NULL))
1290             {
1291               ++errors;
1292               goto cleanup;
1293             }
1294           newhandle = *phandle;
1296           /* Preloaded modules are always named according to their old
1297              archive name.  */
1298           if (strncmp(name, "lib", 3) == 0)
1299             {
1300               sprintf (archive_name, "%s%s.%s", libprefix, name + 3, libext);
1301             }
1302           else
1303             {
1304               sprintf (archive_name, "%s.%s", name, libext);
1305             }
1307           if (tryall_dlopen (&newhandle, archive_name, advise, vtable) == 0)
1308             {
1309               goto register_handle;
1310             }
1312           /* If we're still here, there was no matching preloaded module,
1313              so put things back as we found them, and continue searching.  */
1314           FREE (*phandle);
1315           newhandle = NULL;
1316         }
1317     }
1319   /* If we are allowing only preloaded modules, and we didn't find
1320      anything yet, give up on the search here.  */
1321   if (advise && advise->try_preload_only)
1322     {
1323       goto cleanup;
1324     }
1326   /* Check whether we are opening a libtool module (.la extension).  */
1327   if (ext && streq (ext, archive_ext))
1328     {
1329       /* this seems to be a libtool module */
1330       FILE *    file     = 0;
1331       char *    dlname   = 0;
1332       char *    old_name = 0;
1333       char *    libdir   = 0;
1334       char *    deplibs  = 0;
1336       /* if we can't find the installed flag, it is probably an
1337          installed libtool archive, produced with an old version
1338          of libtool */
1339       int       installed = 1;
1341       /* Now try to open the .la file.  If there is no directory name
1342          component, try to find it first in user_search_path and then other
1343          prescribed paths.  Otherwise (or in any case if the module was not
1344          yet found) try opening just the module name as passed.  */
1345       if (!dir)
1346         {
1347           const char *search_path = user_search_path;
1349           if (search_path)
1350             file = find_file (user_search_path, base_name, &dir);
1352           if (!file)
1353             {
1354               search_path = getenv (LTDL_SEARCHPATH_VAR);
1355               if (search_path)
1356                 file = find_file (search_path, base_name, &dir);
1357             }
1359 #if defined(LT_MODULE_PATH_VAR)
1360           if (!file)
1361             {
1362               search_path = getenv (LT_MODULE_PATH_VAR);
1363               if (search_path)
1364                 file = find_file (search_path, base_name, &dir);
1365             }
1366 #endif
1367 #if defined(LT_DLSEARCH_PATH)
1368           if (!file && *sys_dlsearch_path)
1369             {
1370               file = find_file (sys_dlsearch_path, base_name, &dir);
1371             }
1372 #endif
1373         }
1374       else
1375         {
1376           file = fopen (attempt, LT_READTEXT_MODE);
1377         }
1379       /* If we didn't find the file by now, it really isn't there.  Set
1380          the status flag, and bail out.  */
1381       if (!file)
1382         {
1383           LT__SETERROR (FILE_NOT_FOUND);
1384           ++errors;
1385           goto cleanup;
1386         }
1388       /* read the .la file */
1389       if (parse_dotla_file(file, &dlname, &libdir, &deplibs,
1390             &old_name, &installed) != 0)
1391         ++errors;
1393       fclose (file);
1395       /* allocate the handle */
1396       *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1397       if (*phandle == 0)
1398         ++errors;
1400       if (errors)
1401         {
1402           FREE (dlname);
1403           FREE (old_name);
1404           FREE (libdir);
1405           FREE (deplibs);
1406           FREE (*phandle);
1407           goto cleanup;
1408         }
1410       assert (*phandle);
1412       if (load_deplibs (*phandle, deplibs) == 0)
1413         {
1414           newhandle = *phandle;
1415           /* find_module may replace newhandle */
1416           if (find_module (&newhandle, dir, libdir, dlname, old_name,
1417                            installed, advise))
1418             {
1419               unload_deplibs (*phandle);
1420               ++errors;
1421             }
1422         }
1423       else
1424         {
1425           ++errors;
1426         }
1428       FREE (dlname);
1429       FREE (old_name);
1430       FREE (libdir);
1431       FREE (deplibs);
1433       if (errors)
1434         {
1435           FREE (*phandle);
1436           goto cleanup;
1437         }
1439       if (*phandle != newhandle)
1440         {
1441           unload_deplibs (*phandle);
1442         }
1443     }
1444   else
1445     {
1446       /* not a libtool module */
1447       *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1448       if (*phandle == 0)
1449         {
1450           ++errors;
1451           goto cleanup;
1452         }
1454       newhandle = *phandle;
1456       /* If the module has no directory name component, try to find it
1457          first in user_search_path and then other prescribed paths.
1458          Otherwise (or in any case if the module was not yet found) try
1459          opening just the module name as passed.  */
1460       if ((dir || (!find_handle (user_search_path, base_name,
1461                                  &newhandle, advise)
1462                    && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
1463                                     &newhandle, advise)
1464 #if defined(LT_MODULE_PATH_VAR)
1465                    && !find_handle (getenv (LT_MODULE_PATH_VAR), base_name,
1466                                     &newhandle, advise)
1467 #endif
1468 #if defined(LT_DLSEARCH_PATH)
1469                    && !find_handle (sys_dlsearch_path, base_name,
1470                                     &newhandle, advise)
1471 #endif
1472                    )))
1473         {
1474           if (tryall_dlopen (&newhandle, attempt, advise, 0) != 0)
1475             {
1476               newhandle = NULL;
1477             }
1478         }
1480       if (!newhandle)
1481         {
1482           FREE (*phandle);
1483           ++errors;
1484           goto cleanup;
1485         }
1486     }
1488  register_handle:
1489   MEMREASSIGN (*phandle, newhandle);
1491   if ((*phandle)->info.ref_count == 0)
1492     {
1493       (*phandle)->info.ref_count        = 1;
1494       MEMREASSIGN ((*phandle)->info.name, name);
1496       (*phandle)->next  = handles;
1497       handles           = *phandle;
1498     }
1500   LT__SETERRORSTR (saved_error);
1502  cleanup:
1503   FREE (dir);
1504   FREE (attempt);
1505   FREE (name);
1506   if (!canonical)               /* was MEMREASSIGNed */
1507     FREE (base_name);
1508   FREE (canonical);
1509   FREE (archive_name);
1511   return errors;
1515 /* If the last error message stored was `FILE_NOT_FOUND', then return
1516    non-zero.  */
1517 static int
1518 file_not_found (void)
1520   const char *error = 0;
1522   LT__GETERROR (error);
1523   if (error == LT__STRERROR (FILE_NOT_FOUND))
1524     return 1;
1526   return 0;
1530 /* Unless FILENAME already bears a suitable library extension, then
1531    return 0.  */
1532 static int
1533 has_library_ext (const char *filename)
1535   const char *  ext     = 0;
1537   assert (filename);
1539   ext = strrchr (filename, '.');
1541   if (ext && ((streq (ext, archive_ext))
1542 #if defined(LT_MODULE_EXT)
1543              || (streq (ext, shlib_ext))
1544 #endif
1545 #if defined(LT_SHARED_EXT)
1546              || (streq (ext, shared_ext))
1547 #endif
1548     ))
1549     {
1550       return 1;
1551     }
1553   return 0;
1557 /* Initialise and configure a user lt_dladvise opaque object.  */
1559 int
1560 lt_dladvise_init (lt_dladvise *padvise)
1562   lt_dladvise advise = (lt_dladvise) lt__zalloc (sizeof (struct lt__advise));
1563   *padvise = advise;
1564   return (advise ? 0 : 1);
1567 int
1568 lt_dladvise_destroy (lt_dladvise *padvise)
1570   if (padvise)
1571     FREE(*padvise);
1572   return 0;
1575 int
1576 lt_dladvise_ext (lt_dladvise *padvise)
1578   assert (padvise && *padvise);
1579   (*padvise)->try_ext = 1;
1580   return 0;
1583 int
1584 lt_dladvise_resident (lt_dladvise *padvise)
1586   assert (padvise && *padvise);
1587   (*padvise)->is_resident = 1;
1588   return 0;
1591 int
1592 lt_dladvise_local (lt_dladvise *padvise)
1594   assert (padvise && *padvise);
1595   (*padvise)->is_symlocal = 1;
1596   return 0;
1599 int
1600 lt_dladvise_global (lt_dladvise *padvise)
1602   assert (padvise && *padvise);
1603   (*padvise)->is_symglobal = 1;
1604   return 0;
1607 int
1608 lt_dladvise_preload (lt_dladvise *padvise)
1610   assert (padvise && *padvise);
1611   (*padvise)->try_preload_only = 1;
1612   return 0;
1615 /* Libtool-1.5.x interface for loading a new module named FILENAME.  */
1616 lt_dlhandle
1617 lt_dlopen (const char *filename)
1619   return lt_dlopenadvise (filename, NULL);
1623 /* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to
1624    open the FILENAME as passed.  Otherwise try appending ARCHIVE_EXT,
1625    and if a file is still not found try again with MODULE_EXT appended
1626    instead.  */
1627 lt_dlhandle
1628 lt_dlopenext (const char *filename)
1630   lt_dlhandle   handle  = 0;
1631   lt_dladvise   advise;
1633   if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise))
1634     handle = lt_dlopenadvise (filename, advise);
1636   lt_dladvise_destroy (&advise);
1637   return handle;
1641 lt_dlhandle
1642 lt_dlopenadvise (const char *filename, lt_dladvise advise)
1644   lt_dlhandle   handle  = 0;
1645   int           errors  = 0;
1646   const char *  saved_error     = 0;
1648   LT__GETERROR (saved_error);
1650   /* Can't have symbols hidden and visible at the same time!  */
1651   if (advise && advise->is_symlocal && advise->is_symglobal)
1652     {
1653       LT__SETERROR (CONFLICTING_FLAGS);
1654       return 0;
1655     }
1657   if (!filename
1658       || !advise
1659       || !advise->try_ext
1660       || has_library_ext (filename))
1661     {
1662       /* Just incase we missed a code path in try_dlopen() that reports
1663          an error, but forgot to reset handle... */
1664       if (try_dlopen (&handle, filename, NULL, advise) != 0)
1665         return 0;
1667       return handle;
1668     }
1669   else if (filename && *filename)
1670     {
1672       /* First try appending ARCHIVE_EXT.  */
1673       errors += try_dlopen (&handle, filename, archive_ext, advise);
1675       /* If we found FILENAME, stop searching -- whether we were able to
1676          load the file as a module or not.  If the file exists but loading
1677          failed, it is better to return an error message here than to
1678          report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
1679          in the module search path.  */
1680       if (handle || ((errors > 0) && !file_not_found ()))
1681         return handle;
1683 #if defined(LT_MODULE_EXT)
1684       /* Try appending SHLIB_EXT.   */
1685       LT__SETERRORSTR (saved_error);
1686       errors = try_dlopen (&handle, filename, shlib_ext, advise);
1688       /* As before, if the file was found but loading failed, return now
1689          with the current error message.  */
1690       if (handle || ((errors > 0) && !file_not_found ()))
1691         return handle;
1692 #endif
1694 #if defined(LT_SHARED_EXT)
1695       /* Try appending SHARED_EXT.   */
1696       LT__SETERRORSTR (saved_error);
1697       errors = try_dlopen (&handle, filename, shared_ext, advise);
1699       /* As before, if the file was found but loading failed, return now
1700          with the current error message.  */
1701       if (handle || ((errors > 0) && !file_not_found ()))
1702         return handle;
1703 #endif
1704     }
1706   /* Still here?  Then we really did fail to locate any of the file
1707      names we tried.  */
1708   LT__SETERROR (FILE_NOT_FOUND);
1709   return 0;
1713 static int
1714 lt_argz_insert (char **pargz, size_t *pargz_len, char *before,
1715                 const char *entry)
1717   error_t error;
1719   /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
1720      pargz_len, NULL, entry) failed with EINVAL.  */
1721   if (before)
1722     error = argz_insert (pargz, pargz_len, before, entry);
1723   else
1724     error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry));
1726   if (error)
1727     {
1728       switch (error)
1729         {
1730         case ENOMEM:
1731           LT__SETERROR (NO_MEMORY);
1732           break;
1733         default:
1734           LT__SETERROR (UNKNOWN);
1735           break;
1736         }
1737       return 1;
1738     }
1740   return 0;
1743 static int
1744 lt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry)
1746   char *before = 0;
1748   assert (pargz);
1749   assert (pargz_len);
1750   assert (entry && *entry);
1752   if (*pargz)
1753     while ((before = argz_next (*pargz, *pargz_len, before)))
1754       {
1755         int cmp = strcmp (entry, before);
1757         if (cmp < 0)  break;
1758         if (cmp == 0) return 0; /* No duplicates! */
1759       }
1761   return lt_argz_insert (pargz, pargz_len, before, entry);
1764 static int
1765 lt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam,
1766                    struct dirent *dp)
1768   char   *buf       = 0;
1769   size_t buf_len    = 0;
1770   char   *end       = 0;
1771   size_t end_offset = 0;
1772   size_t dir_len    = 0;
1773   int    errors     = 0;
1775   assert (pargz);
1776   assert (pargz_len);
1777   assert (dp);
1779   dir_len = LT_STRLEN (dirnam);
1780   end     = dp->d_name + D_NAMLEN(dp);
1782   /* Ignore version numbers.  */
1783   {
1784     char *p;
1785     for (p = end; p -1 > dp->d_name; --p)
1786       if (strchr (".0123456789", p[-1]) == 0)
1787         break;
1789     if (*p == '.')
1790       end = p;
1791   }
1793   /* Ignore filename extension.  */
1794   {
1795     char *p;
1796     for (p = end -1; p > dp->d_name; --p)
1797       if (*p == '.')
1798         {
1799           end = p;
1800           break;
1801         }
1802   }
1804   /* Prepend the directory name.  */
1805   end_offset    = end - dp->d_name;
1806   buf_len       = dir_len + 1+ end_offset;
1807   buf           = MALLOC (char, 1+ buf_len);
1808   if (!buf)
1809     return ++errors;
1811   assert (buf);
1813   strcpy  (buf, dirnam);
1814   strcat  (buf, "/");
1815   strncat (buf, dp->d_name, end_offset);
1816   buf[buf_len] = LT_EOS_CHAR;
1818   /* Try to insert (in order) into ARGZ/ARGZ_LEN.  */
1819   if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
1820     ++errors;
1822   FREE (buf);
1824   return errors;
1827 static int
1828 list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len)
1830   DIR   *dirp     = 0;
1831   int    errors   = 0;
1833   assert (dirnam && *dirnam);
1834   assert (pargz);
1835   assert (pargz_len);
1836   assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
1838   dirp = opendir (dirnam);
1839   if (dirp)
1840     {
1841       struct dirent *dp = 0;
1843       while ((dp = readdir (dirp)))
1844         if (dp->d_name[0] != '.')
1845           if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
1846             {
1847               ++errors;
1848               break;
1849             }
1851       closedir (dirp);
1852     }
1853   else
1854     ++errors;
1856   return errors;
1860 /* If there are any files in DIRNAME, call the function passed in
1861    DATA1 (with the name of each file and DATA2 as arguments).  */
1862 static int
1863 foreachfile_callback (char *dirname, void *data1, void *data2)
1865   file_worker_func *func = *(file_worker_func **) data1;
1867   int     is_done  = 0;
1868   char   *argz     = 0;
1869   size_t  argz_len = 0;
1871   if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
1872     goto cleanup;
1873   if (!argz)
1874     goto cleanup;
1876   {
1877     char *filename = 0;
1878     while ((filename = argz_next (argz, argz_len, filename)))
1879       if ((is_done = (*func) (filename, data2)))
1880         break;
1881   }
1883  cleanup:
1884   FREE (argz);
1886   return is_done;
1890 /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
1891    with DATA.  The filenames passed to FUNC would be suitable for
1892    passing to lt_dlopenext.  The extensions are stripped so that
1893    individual modules do not generate several entries (e.g. libfoo.la,
1894    libfoo.so, libfoo.so.1, libfoo.so.1.0.0).  If SEARCH_PATH is NULL,
1895    then the same directories that lt_dlopen would search are examined.  */
1896 int
1897 lt_dlforeachfile (const char *search_path,
1898                   int (*func) (const char *filename, void *data),
1899                   void *data)
1901   int is_done = 0;
1902   file_worker_func **fpptr = &func;
1904   if (search_path)
1905     {
1906       /* If a specific path was passed, search only the directories
1907          listed in it.  */
1908       is_done = foreach_dirinpath (search_path, 0,
1909                                    foreachfile_callback, fpptr, data);
1910     }
1911   else
1912     {
1913       /* Otherwise search the default paths.  */
1914       is_done = foreach_dirinpath (user_search_path, 0,
1915                                    foreachfile_callback, fpptr, data);
1916       if (!is_done)
1917         {
1918           is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0,
1919                                        foreachfile_callback, fpptr, data);
1920         }
1922 #if defined(LT_MODULE_PATH_VAR)
1923       if (!is_done)
1924         {
1925           is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0,
1926                                        foreachfile_callback, fpptr, data);
1927         }
1928 #endif
1929 #if defined(LT_DLSEARCH_PATH)
1930       if (!is_done && *sys_dlsearch_path)
1931         {
1932           is_done = foreach_dirinpath (sys_dlsearch_path, 0,
1933                                        foreachfile_callback, fpptr, data);
1934         }
1935 #endif
1936     }
1938   return is_done;
1941 int
1942 lt_dlclose (lt_dlhandle handle)
1944   lt_dlhandle cur, last;
1945   int errors = 0;
1947   /* check whether the handle is valid */
1948   last = cur = handles;
1949   while (cur && handle != cur)
1950     {
1951       last = cur;
1952       cur = cur->next;
1953     }
1955   if (!cur)
1956     {
1957       LT__SETERROR (INVALID_HANDLE);
1958       ++errors;
1959       goto done;
1960     }
1962   cur = handle;
1963   cur->info.ref_count--;
1965   /* Note that even with resident modules, we must track the ref_count
1966      correctly incase the user decides to reset the residency flag
1967      later (even though the API makes no provision for that at the
1968      moment).  */
1969   if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur))
1970     {
1971       lt_user_data data = cur->vtable->dlloader_data;
1973       if (cur != handles)
1974         {
1975           last->next = cur->next;
1976         }
1977       else
1978         {
1979           handles = cur->next;
1980         }
1982       errors += cur->vtable->module_close (data, cur->module);
1983       errors += unload_deplibs (handle);
1985       /* It is up to the callers to free the data itself.  */
1986       FREE (cur->interface_data);
1988       FREE (cur->info.filename);
1989       FREE (cur->info.name);
1990       FREE (cur);
1992       goto done;
1993     }
1995   if (LT_DLIS_RESIDENT (handle))
1996     {
1997       LT__SETERROR (CLOSE_RESIDENT_MODULE);
1998       ++errors;
1999     }
2001  done:
2002   return errors;
2005 void *
2006 lt_dlsym (lt_dlhandle place, const char *symbol)
2008   size_t lensym;
2009   char  lsym[LT_SYMBOL_LENGTH];
2010   char  *sym;
2011   void *address;
2012   lt_user_data data;
2013   lt_dlhandle handle;
2015   if (!place)
2016     {
2017       LT__SETERROR (INVALID_HANDLE);
2018       return 0;
2019     }
2021   handle = place;
2023   if (!symbol)
2024     {
2025       LT__SETERROR (SYMBOL_NOT_FOUND);
2026       return 0;
2027     }
2029   lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->vtable->sym_prefix)
2030                                         + LT_STRLEN (handle->info.name);
2032   if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
2033     {
2034       sym = lsym;
2035     }
2036   else
2037     {
2038       sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
2039       if (!sym)
2040         {
2041           LT__SETERROR (BUFFER_OVERFLOW);
2042           return 0;
2043         }
2044     }
2046   data = handle->vtable->dlloader_data;
2047   if (handle->info.name)
2048     {
2049       const char *saved_error;
2051       LT__GETERROR (saved_error);
2053       /* this is a libtool module */
2054       if (handle->vtable->sym_prefix)
2055         {
2056           strcpy(sym, handle->vtable->sym_prefix);
2057           strcat(sym, handle->info.name);
2058         }
2059       else
2060         {
2061           strcpy(sym, handle->info.name);
2062         }
2064       strcat(sym, "_LTX_");
2065       strcat(sym, symbol);
2067       /* try "modulename_LTX_symbol" */
2068       address = handle->vtable->find_sym (data, handle->module, sym);
2069       if (address)
2070         {
2071           if (sym != lsym)
2072             {
2073               FREE (sym);
2074             }
2075           return address;
2076         }
2077       LT__SETERRORSTR (saved_error);
2078     }
2080   /* otherwise try "symbol" */
2081   if (handle->vtable->sym_prefix)
2082     {
2083       strcpy(sym, handle->vtable->sym_prefix);
2084       strcat(sym, symbol);
2085     }
2086   else
2087     {
2088       strcpy(sym, symbol);
2089     }
2091   address = handle->vtable->find_sym (data, handle->module, sym);
2092   if (sym != lsym)
2093     {
2094       FREE (sym);
2095     }
2097   return address;
2100 const char *
2101 lt_dlerror (void)
2103   const char *error;
2105   LT__GETERROR (error);
2106   LT__SETERRORSTR (0);
2108   return error;
2111 static int
2112 lt_dlpath_insertdir (char **ppath, char *before, const char *dir)
2114   int    errors         = 0;
2115   char  *canonical      = 0;
2116   char  *argz           = 0;
2117   size_t argz_len       = 0;
2119   assert (ppath);
2120   assert (dir && *dir);
2122   if (canonicalize_path (dir, &canonical) != 0)
2123     {
2124       ++errors;
2125       goto cleanup;
2126     }
2128   assert (canonical && *canonical);
2130   /* If *PPATH is empty, set it to DIR.  */
2131   if (*ppath == 0)
2132     {
2133       assert (!before);         /* BEFORE cannot be set without PPATH.  */
2134       assert (dir);             /* Without DIR, don't call this function!  */
2136       *ppath = lt__strdup (dir);
2137       if (*ppath == 0)
2138         ++errors;
2140       goto cleanup;
2141     }
2143   assert (ppath && *ppath);
2145   if (argzize_path (*ppath, &argz, &argz_len) != 0)
2146     {
2147       ++errors;
2148       goto cleanup;
2149     }
2151   /* Convert BEFORE into an equivalent offset into ARGZ.  This only works
2152      if *PPATH is already canonicalized, and hence does not change length
2153      with respect to ARGZ.  We canonicalize each entry as it is added to
2154      the search path, and don't call this function with (uncanonicalized)
2155      user paths, so this is a fair assumption.  */
2156   if (before)
2157     {
2158       assert (*ppath <= before);
2159       assert ((int) (before - *ppath) <= (int) strlen (*ppath));
2161       before = before - *ppath + argz;
2162     }
2164   if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
2165     {
2166       ++errors;
2167       goto cleanup;
2168     }
2170   argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
2171   MEMREASSIGN(*ppath, argz);
2173  cleanup:
2174   FREE (argz);
2175   FREE (canonical);
2177   return errors;
2180 int
2181 lt_dladdsearchdir (const char *search_dir)
2183   int errors = 0;
2185   if (search_dir && *search_dir)
2186     {
2187       if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
2188         ++errors;
2189     }
2191   return errors;
2194 int
2195 lt_dlinsertsearchdir (const char *before, const char *search_dir)
2197   int errors = 0;
2199   if (before)
2200     {
2201       if ((before < user_search_path)
2202           || (before >= user_search_path + LT_STRLEN (user_search_path)))
2203         {
2204           LT__SETERROR (INVALID_POSITION);
2205           return 1;
2206         }
2207     }
2209   if (search_dir && *search_dir)
2210     {
2211       if (lt_dlpath_insertdir (&user_search_path,
2212                                (char *) before, search_dir) != 0)
2213         {
2214           ++errors;
2215         }
2216     }
2218   return errors;
2221 int
2222 lt_dlsetsearchpath (const char *search_path)
2224   int   errors      = 0;
2226   FREE (user_search_path);
2228   if (!search_path || !LT_STRLEN (search_path))
2229     {
2230       return errors;
2231     }
2233   if (canonicalize_path (search_path, &user_search_path) != 0)
2234     ++errors;
2236   return errors;
2239 const char *
2240 lt_dlgetsearchpath (void)
2242   const char *saved_path;
2244   saved_path = user_search_path;
2246   return saved_path;
2249 int
2250 lt_dlmakeresident (lt_dlhandle handle)
2252   int errors = 0;
2254   if (!handle)
2255     {
2256       LT__SETERROR (INVALID_HANDLE);
2257       ++errors;
2258     }
2259   else
2260     {
2261       handle->info.is_resident = 1;
2262     }
2264   return errors;
2267 int
2268 lt_dlisresident (lt_dlhandle handle)
2270   if (!handle)
2271     {
2272       LT__SETERROR (INVALID_HANDLE);
2273       return -1;
2274     }
2276   return LT_DLIS_RESIDENT (handle);
2281 /* --- MODULE INFORMATION --- */
2283 typedef struct {
2284   const char *id_string;
2285   lt_dlhandle_interface *iface;
2286 } lt__interface_id;
2288 lt_dlinterface_id
2289 lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface)
2291   lt__interface_id *interface_id = (lt__interface_id *) lt__malloc (sizeof *interface_id);
2293   /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which
2294      can then be detected with lt_dlerror() if we return 0.  */
2295   if (interface_id)
2296     {
2297       interface_id->id_string = lt__strdup (id_string);
2298       if (!interface_id->id_string)
2299         FREE (interface_id);
2300       else
2301         interface_id->iface = iface;
2302     }
2304   return (lt_dlinterface_id) interface_id;
2307 void lt_dlinterface_free (lt_dlinterface_id key)
2309   lt__interface_id *interface_id = (lt__interface_id *)key;
2310   FREE (interface_id->id_string);
2311   FREE (interface_id);
2314 void *
2315 lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data)
2317   int n_elements = 0;
2318   void *stale = (void *) 0;
2319   lt_dlhandle cur = handle;
2320   int i;
2322   if (cur->interface_data)
2323     while (cur->interface_data[n_elements].key)
2324       ++n_elements;
2326   for (i = 0; i < n_elements; ++i)
2327     {
2328       if (cur->interface_data[i].key == key)
2329         {
2330           stale = cur->interface_data[i].data;
2331           break;
2332         }
2333     }
2335   /* Ensure that there is enough room in this handle's interface_data
2336      array to accept a new element (and an empty end marker).  */
2337   if (i == n_elements)
2338     {
2339       lt_interface_data *temp
2340         = REALLOC (lt_interface_data, cur->interface_data, 2+ n_elements);
2342       if (!temp)
2343         {
2344           stale = 0;
2345           goto done;
2346         }
2348       cur->interface_data = temp;
2350       /* We only need this if we needed to allocate a new interface_data.  */
2351       cur->interface_data[i].key        = key;
2352       cur->interface_data[1+ i].key     = 0;
2353     }
2355   cur->interface_data[i].data = data;
2357  done:
2358   return stale;
2361 void *
2362 lt_dlcaller_get_data (lt_dlinterface_id key, lt_dlhandle handle)
2364   void *result = (void *) 0;
2365   lt_dlhandle cur = handle;
2367   /* Locate the index of the element with a matching KEY.  */
2368   if (cur->interface_data)
2369     {
2370       int i;
2371       for (i = 0; cur->interface_data[i].key; ++i)
2372         {
2373           if (cur->interface_data[i].key == key)
2374             {
2375               result = cur->interface_data[i].data;
2376               break;
2377             }
2378         }
2379     }
2381   return result;
2384 const lt_dlinfo *
2385 lt_dlgetinfo (lt_dlhandle handle)
2387   if (!handle)
2388     {
2389       LT__SETERROR (INVALID_HANDLE);
2390       return 0;
2391     }
2393   return &(handle->info);
2397 lt_dlhandle
2398 lt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place)
2400   lt_dlhandle handle = place;
2401   lt__interface_id *iterator = (lt__interface_id *) iface;
2403   assert (iface); /* iface is a required argument */
2405   if (!handle)
2406     handle = handles;
2407   else
2408     handle = handle->next;
2410   /* advance while the interface check fails */
2411   while (handle && iterator->iface
2412          && ((*iterator->iface) (handle, iterator->id_string) != 0))
2413     {
2414       handle = handle->next;
2415     }
2417   return handle;
2421 lt_dlhandle
2422 lt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name)
2424   lt_dlhandle handle = 0;
2426   assert (iface); /* iface is a required argument */
2428   while ((handle = lt_dlhandle_iterate (iface, handle)))
2429     {
2430       lt_dlhandle cur = handle;
2431       if (cur && cur->info.name && streq (cur->info.name, module_name))
2432         break;
2433     }
2435   return handle;
2439 int
2440 lt_dlhandle_map (lt_dlinterface_id iface,
2441                  int (*func) (lt_dlhandle handle, void *data), void *data)
2443   lt__interface_id *iterator = (lt__interface_id *) iface;
2444   lt_dlhandle cur = handles;
2446   assert (iface); /* iface is a required argument */
2448   while (cur)
2449     {
2450       int errorcode = 0;
2452       /* advance while the interface check fails */
2453       while (cur && iterator->iface
2454              && ((*iterator->iface) (cur, iterator->id_string) != 0))
2455         {
2456           cur = cur->next;
2457         }
2459       if ((errorcode = (*func) (cur, data)) != 0)
2460         return errorcode;
2461     }
2463   return 0;