ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/libltdl/ltdl.c
Revision: 1028
Committed: Sun Nov 8 13:03:38 2009 UTC (16 years, 8 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/libltdl/ltdl.c
File size: 53895 byte(s)
Log Message:
- move ircd-hybrid-7.2 to trunk

File Contents

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

Properties

Name Value
svn:eol-style native