ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.3/libltdl/ltdl.c
Revision: 1094
Committed: Sun Jun 13 10:09:34 2010 UTC (16 years, 1 month ago) by michael
Content type: text/x-csrc
File size: 54147 byte(s)
Log Message:
- Updated ltdl to latest 2.2.10 release

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 michael 1094 extern lt_dlsymlist preloaded_symbols[];
212 michael 945 #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 michael 1094 errors += lt_dlpreload (preloaded_symbols);
238 michael 945 }
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 michael 1037 if (old_name && tryall_dlopen (handle, old_name,
533     advise, lt_dlloader_find ("lt_preopen") ) == 0)
534 michael 945 {
535     return 0;
536     }
537    
538     /* Try to open the dynamic library. */
539     if (dlname)
540     {
541     /* try to open the installed module */
542     if (installed && libdir)
543     {
544     if (tryall_dlopen_module (handle, (const char *) 0,
545     libdir, dlname, advise) == 0)
546     return 0;
547     }
548    
549     /* try to open the not-installed module */
550     if (!installed)
551     {
552     if (tryall_dlopen_module (handle, dir, objdir,
553     dlname, advise) == 0)
554     return 0;
555     }
556    
557     /* maybe it was moved to another directory */
558     {
559     if (dir && (tryall_dlopen_module (handle, (const char *) 0,
560     dir, dlname, advise) == 0))
561     return 0;
562     }
563     }
564    
565     return 1;
566     }
567    
568    
569     static int
570     canonicalize_path (const char *path, char **pcanonical)
571     {
572     char *canonical = 0;
573    
574     assert (path && *path);
575     assert (pcanonical);
576    
577     canonical = MALLOC (char, 1+ LT_STRLEN (path));
578     if (!canonical)
579     return 1;
580    
581     {
582     size_t dest = 0;
583     size_t src;
584     for (src = 0; path[src] != LT_EOS_CHAR; ++src)
585     {
586     /* Path separators are not copied to the beginning or end of
587     the destination, or if another separator would follow
588     immediately. */
589     if (path[src] == LT_PATHSEP_CHAR)
590     {
591     if ((dest == 0)
592     || (path[1+ src] == LT_PATHSEP_CHAR)
593     || (path[1+ src] == LT_EOS_CHAR))
594     continue;
595     }
596    
597     /* Anything other than a directory separator is copied verbatim. */
598     if ((path[src] != '/')
599     #if defined(LT_DIRSEP_CHAR)
600     && (path[src] != LT_DIRSEP_CHAR)
601     #endif
602     )
603     {
604     canonical[dest++] = path[src];
605     }
606     /* Directory separators are converted and copied only if they are
607     not at the end of a path -- i.e. before a path separator or
608     NULL terminator. */
609     else if ((path[1+ src] != LT_PATHSEP_CHAR)
610     && (path[1+ src] != LT_EOS_CHAR)
611     #if defined(LT_DIRSEP_CHAR)
612     && (path[1+ src] != LT_DIRSEP_CHAR)
613     #endif
614     && (path[1+ src] != '/'))
615     {
616     canonical[dest++] = '/';
617     }
618     }
619    
620     /* Add an end-of-string marker at the end. */
621     canonical[dest] = LT_EOS_CHAR;
622     }
623    
624     /* Assign new value. */
625     *pcanonical = canonical;
626    
627     return 0;
628     }
629    
630     static int
631     argzize_path (const char *path, char **pargz, size_t *pargz_len)
632     {
633     error_t error;
634    
635     assert (path);
636     assert (pargz);
637     assert (pargz_len);
638    
639     if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
640     {
641     switch (error)
642     {
643     case ENOMEM:
644     LT__SETERROR (NO_MEMORY);
645     break;
646     default:
647     LT__SETERROR (UNKNOWN);
648     break;
649     }
650    
651     return 1;
652     }
653    
654     return 0;
655     }
656    
657     /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
658     of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
659     non-zero or all elements are exhausted. If BASE_NAME is non-NULL,
660     it is appended to each SEARCH_PATH element before FUNC is called. */
661     static int
662     foreach_dirinpath (const char *search_path, const char *base_name,
663     foreach_callback_func *func, void *data1, void *data2)
664     {
665     int result = 0;
666     size_t filenamesize = 0;
667     size_t lenbase = LT_STRLEN (base_name);
668     size_t argz_len = 0;
669     char *argz = 0;
670     char *filename = 0;
671     char *canonical = 0;
672    
673     if (!search_path || !*search_path)
674     {
675     LT__SETERROR (FILE_NOT_FOUND);
676     goto cleanup;
677     }
678    
679     if (canonicalize_path (search_path, &canonical) != 0)
680     goto cleanup;
681    
682     if (argzize_path (canonical, &argz, &argz_len) != 0)
683     goto cleanup;
684    
685     {
686     char *dir_name = 0;
687     while ((dir_name = argz_next (argz, argz_len, dir_name)))
688     {
689     size_t lendir = LT_STRLEN (dir_name);
690    
691     if (1+ lendir + lenbase >= filenamesize)
692     {
693     FREE (filename);
694     filenamesize = 1+ lendir + 1+ lenbase; /* "/d" + '/' + "f" + '\0' */
695     filename = MALLOC (char, filenamesize);
696     if (!filename)
697     goto cleanup;
698     }
699    
700     assert (filenamesize > lendir);
701     strcpy (filename, dir_name);
702    
703     if (base_name && *base_name)
704     {
705     if (filename[lendir -1] != '/')
706     filename[lendir++] = '/';
707     strcpy (filename +lendir, base_name);
708     }
709    
710     if ((result = (*func) (filename, data1, data2)))
711     {
712     break;
713     }
714     }
715     }
716    
717     cleanup:
718     FREE (argz);
719     FREE (canonical);
720     FREE (filename);
721    
722     return result;
723     }
724    
725     /* If FILEPATH can be opened, store the name of the directory component
726     in DATA1, and the opened FILE* structure address in DATA2. Otherwise
727     DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */
728     static int
729     find_file_callback (char *filename, void *data1, void *data2)
730     {
731     char **pdir = (char **) data1;
732     FILE **pfile = (FILE **) data2;
733     int is_done = 0;
734    
735     assert (filename && *filename);
736     assert (pdir);
737     assert (pfile);
738    
739     if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
740     {
741     char *dirend = strrchr (filename, '/');
742    
743     if (dirend > filename)
744     *dirend = LT_EOS_CHAR;
745    
746     FREE (*pdir);
747     *pdir = lt__strdup (filename);
748     is_done = (*pdir == 0) ? -1 : 1;
749     }
750    
751     return is_done;
752     }
753    
754     static FILE *
755     find_file (const char *search_path, const char *base_name, char **pdir)
756     {
757     FILE *file = 0;
758    
759     foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
760    
761     return file;
762     }
763    
764     static int
765     find_handle_callback (char *filename, void *data, void *data2)
766     {
767     lt_dlhandle *phandle = (lt_dlhandle *) data;
768     int notfound = access (filename, R_OK);
769     lt_dladvise advise = (lt_dladvise) data2;
770    
771     /* Bail out if file cannot be read... */
772     if (notfound)
773     return 0;
774    
775     /* Try to dlopen the file, but do not continue searching in any
776     case. */
777     if (tryall_dlopen (phandle, filename, advise, 0) != 0)
778     *phandle = 0;
779    
780     return 1;
781     }
782    
783     /* If HANDLE was found return it, otherwise return 0. If HANDLE was
784     found but could not be opened, *HANDLE will be set to 0. */
785     static lt_dlhandle *
786     find_handle (const char *search_path, const char *base_name,
787     lt_dlhandle *phandle, lt_dladvise advise)
788     {
789     if (!search_path)
790     return 0;
791    
792     if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
793     phandle, advise))
794     return 0;
795    
796     return phandle;
797     }
798    
799     #if !defined(LTDL_DLOPEN_DEPLIBS)
800     static int
801     load_deplibs (lt_dlhandle handle, char * LT__UNUSED deplibs)
802     {
803     handle->depcount = 0;
804     return 0;
805     }
806    
807     #else /* defined(LTDL_DLOPEN_DEPLIBS) */
808     static int
809     load_deplibs (lt_dlhandle handle, char *deplibs)
810     {
811     char *p, *save_search_path = 0;
812     int depcount = 0;
813     int i;
814     char **names = 0;
815     int errors = 0;
816    
817     handle->depcount = 0;
818    
819     if (!deplibs)
820     {
821     return errors;
822     }
823     ++errors;
824    
825     if (user_search_path)
826     {
827     save_search_path = lt__strdup (user_search_path);
828     if (!save_search_path)
829     goto cleanup;
830     }
831    
832     /* extract search paths and count deplibs */
833     p = deplibs;
834     while (*p)
835     {
836     if (!isspace ((unsigned char) *p))
837     {
838     char *end = p+1;
839     while (*end && !isspace((unsigned char) *end))
840     {
841     ++end;
842     }
843    
844     if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0)
845     {
846     char save = *end;
847     *end = 0; /* set a temporary string terminator */
848     if (lt_dladdsearchdir(p+2))
849     {
850     goto cleanup;
851     }
852     *end = save;
853     }
854     else
855     {
856     ++depcount;
857     }
858    
859     p = end;
860     }
861     else
862     {
863     ++p;
864     }
865     }
866    
867    
868     if (!depcount)
869     {
870     errors = 0;
871     goto cleanup;
872     }
873    
874     names = MALLOC (char *, depcount);
875     if (!names)
876     goto cleanup;
877    
878     /* now only extract the actual deplibs */
879     depcount = 0;
880     p = deplibs;
881     while (*p)
882     {
883     if (isspace ((unsigned char) *p))
884     {
885     ++p;
886     }
887     else
888     {
889     char *end = p+1;
890     while (*end && !isspace ((unsigned char) *end))
891     {
892     ++end;
893     }
894    
895     if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0)
896     {
897     char *name;
898     char save = *end;
899     *end = 0; /* set a temporary string terminator */
900     if (strncmp(p, "-l", 2) == 0)
901     {
902     size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
903     name = MALLOC (char, 1+ name_len);
904     if (name)
905     sprintf (name, "lib%s", p+2);
906     }
907     else
908     name = lt__strdup(p);
909    
910     if (!name)
911     goto cleanup_names;
912    
913     names[depcount++] = name;
914     *end = save;
915     }
916     p = end;
917     }
918     }
919    
920     /* load the deplibs (in reverse order)
921     At this stage, don't worry if the deplibs do not load correctly,
922     they may already be statically linked into the loading application
923     for instance. There will be a more enlightening error message
924     later on if the loaded module cannot resolve all of its symbols. */
925     if (depcount)
926     {
927     lt_dlhandle cur = handle;
928     int j = 0;
929    
930     cur->deplibs = MALLOC (lt_dlhandle, depcount);
931     if (!cur->deplibs)
932     goto cleanup_names;
933    
934     for (i = 0; i < depcount; ++i)
935     {
936     cur->deplibs[j] = lt_dlopenext(names[depcount-1-i]);
937     if (cur->deplibs[j])
938     {
939     ++j;
940     }
941     }
942    
943     cur->depcount = j; /* Number of successfully loaded deplibs */
944     errors = 0;
945     }
946    
947     cleanup_names:
948     for (i = 0; i < depcount; ++i)
949     {
950     FREE (names[i]);
951     }
952    
953     cleanup:
954     FREE (names);
955     /* restore the old search path */
956     if (save_search_path) {
957     MEMREASSIGN (user_search_path, save_search_path);
958     }
959    
960     return errors;
961     }
962     #endif /* defined(LTDL_DLOPEN_DEPLIBS) */
963    
964     static int
965     unload_deplibs (lt_dlhandle handle)
966     {
967     int i;
968     int errors = 0;
969     lt_dlhandle cur = handle;
970    
971     if (cur->depcount)
972     {
973     for (i = 0; i < cur->depcount; ++i)
974     {
975     if (!LT_DLIS_RESIDENT (cur->deplibs[i]))
976     {
977     errors += lt_dlclose (cur->deplibs[i]);
978     }
979     }
980     FREE (cur->deplibs);
981     }
982    
983     return errors;
984     }
985    
986     static int
987     trim (char **dest, const char *str)
988     {
989     /* remove the leading and trailing "'" from str
990     and store the result in dest */
991     const char *end = strrchr (str, '\'');
992     size_t len = LT_STRLEN (str);
993     char *tmp;
994    
995     FREE (*dest);
996    
997 michael 1094 if (!end || end == str)
998 michael 945 return 1;
999    
1000     if (len > 3 && str[0] == '\'')
1001     {
1002     tmp = MALLOC (char, end - str);
1003     if (!tmp)
1004     return 1;
1005    
1006     memcpy(tmp, &str[1], (end - str) - 1);
1007     tmp[(end - str) - 1] = LT_EOS_CHAR;
1008     *dest = tmp;
1009     }
1010     else
1011     {
1012     *dest = 0;
1013     }
1014    
1015     return 0;
1016     }
1017    
1018     /* Read the .la file FILE. */
1019     static int
1020     parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs,
1021     char **old_name, int *installed)
1022     {
1023     int errors = 0;
1024     size_t line_len = LT_FILENAME_MAX;
1025     char * line = MALLOC (char, line_len);
1026    
1027     if (!line)
1028     {
1029     LT__SETERROR (FILE_NOT_FOUND);
1030     return 1;
1031     }
1032    
1033     while (!feof (file))
1034     {
1035     line[line_len-2] = '\0';
1036     if (!fgets (line, (int) line_len, file))
1037     {
1038     break;
1039     }
1040    
1041     /* Handle the case where we occasionally need to read a line
1042     that is longer than the initial buffer size.
1043     Behave even if the file contains NUL bytes due to corruption. */
1044     while (line[line_len-2] != '\0' && line[line_len-2] != '\n' && !feof (file))
1045     {
1046     line = REALLOC (char, line, line_len *2);
1047     if (!line)
1048     {
1049     ++errors;
1050     goto cleanup;
1051     }
1052     line[line_len * 2 - 2] = '\0';
1053     if (!fgets (&line[line_len -1], (int) line_len +1, file))
1054     {
1055     break;
1056     }
1057     line_len *= 2;
1058     }
1059    
1060     if (line[0] == '\n' || line[0] == '#')
1061     {
1062     continue;
1063     }
1064    
1065     #undef STR_DLNAME
1066     #define STR_DLNAME "dlname="
1067     if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
1068     {
1069     errors += trim (dlname, &line[sizeof (STR_DLNAME) - 1]);
1070     }
1071    
1072     #undef STR_OLD_LIBRARY
1073     #define STR_OLD_LIBRARY "old_library="
1074     else if (strncmp (line, STR_OLD_LIBRARY,
1075     sizeof (STR_OLD_LIBRARY) - 1) == 0)
1076     {
1077     errors += trim (old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
1078     }
1079 michael 1094
1080     /* Windows native tools do not understand the POSIX paths we store
1081     in libdir. */
1082     #ifndef __WINDOWS__
1083 michael 945 #undef STR_LIBDIR
1084     #define STR_LIBDIR "libdir="
1085     else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
1086     {
1087     errors += trim (libdir, &line[sizeof(STR_LIBDIR) - 1]);
1088     }
1089 michael 1094 #endif
1090 michael 945
1091     #undef STR_DL_DEPLIBS
1092     #define STR_DL_DEPLIBS "dependency_libs="
1093     else if (strncmp (line, STR_DL_DEPLIBS,
1094     sizeof (STR_DL_DEPLIBS) - 1) == 0)
1095     {
1096     errors += trim (deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
1097     }
1098     else if (streq (line, "installed=yes\n"))
1099     {
1100     *installed = 1;
1101     }
1102     else if (streq (line, "installed=no\n"))
1103     {
1104     *installed = 0;
1105     }
1106    
1107     #undef STR_LIBRARY_NAMES
1108     #define STR_LIBRARY_NAMES "library_names="
1109     else if (!*dlname && strncmp (line, STR_LIBRARY_NAMES,
1110     sizeof (STR_LIBRARY_NAMES) - 1) == 0)
1111     {
1112     char *last_libname;
1113     errors += trim (dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
1114     if (!errors
1115     && *dlname
1116     && (last_libname = strrchr (*dlname, ' ')) != 0)
1117     {
1118     last_libname = lt__strdup (last_libname + 1);
1119     if (!last_libname)
1120     {
1121     ++errors;
1122     goto cleanup;
1123     }
1124     MEMREASSIGN (*dlname, last_libname);
1125     }
1126     }
1127    
1128     if (errors)
1129     break;
1130     }
1131     cleanup:
1132     FREE (line);
1133     return errors;
1134     }
1135    
1136    
1137     /* Try to open FILENAME as a module. */
1138     static int
1139     try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext,
1140     lt_dladvise advise)
1141     {
1142     const char * saved_error = 0;
1143     char * archive_name = 0;
1144     char * canonical = 0;
1145     char * base_name = 0;
1146     char * dir = 0;
1147     char * name = 0;
1148     char * attempt = 0;
1149     int errors = 0;
1150     lt_dlhandle newhandle;
1151    
1152     assert (phandle);
1153     assert (*phandle == 0);
1154    
1155     #ifdef LT_DEBUG_LOADERS
1156     fprintf (stderr, "try_dlopen (%s, %s)\n",
1157     filename ? filename : "(null)",
1158     ext ? ext : "(null)");
1159     #endif
1160    
1161     LT__GETERROR (saved_error);
1162    
1163     /* dlopen self? */
1164     if (!filename)
1165     {
1166     *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1167     if (*phandle == 0)
1168     return 1;
1169    
1170     newhandle = *phandle;
1171    
1172     /* lt_dlclose()ing yourself is very bad! Disallow it. */
1173     newhandle->info.is_resident = 1;
1174    
1175     if (tryall_dlopen (&newhandle, 0, advise, 0) != 0)
1176     {
1177     FREE (*phandle);
1178     return 1;
1179     }
1180    
1181     goto register_handle;
1182     }
1183    
1184     assert (filename && *filename);
1185    
1186     if (ext)
1187     {
1188     attempt = MALLOC (char, LT_STRLEN (filename) + LT_STRLEN (ext) + 1);
1189     if (!attempt)
1190     return 1;
1191    
1192     sprintf(attempt, "%s%s", filename, ext);
1193     }
1194     else
1195     {
1196     attempt = lt__strdup (filename);
1197     if (!attempt)
1198     return 1;
1199     }
1200    
1201     /* Doing this immediately allows internal functions to safely
1202     assume only canonicalized paths are passed. */
1203     if (canonicalize_path (attempt, &canonical) != 0)
1204     {
1205     ++errors;
1206     goto cleanup;
1207     }
1208    
1209     /* If the canonical module name is a path (relative or absolute)
1210     then split it into a directory part and a name part. */
1211     base_name = strrchr (canonical, '/');
1212     if (base_name)
1213     {
1214     size_t dirlen = (1+ base_name) - canonical;
1215    
1216     dir = MALLOC (char, 1+ dirlen);
1217     if (!dir)
1218     {
1219     ++errors;
1220     goto cleanup;
1221     }
1222    
1223     strncpy (dir, canonical, dirlen);
1224     dir[dirlen] = LT_EOS_CHAR;
1225    
1226     ++base_name;
1227     }
1228     else
1229     MEMREASSIGN (base_name, canonical);
1230    
1231     assert (base_name && *base_name);
1232    
1233     ext = strrchr (base_name, '.');
1234     if (!ext)
1235     {
1236     ext = base_name + LT_STRLEN (base_name);
1237     }
1238    
1239     /* extract the module name from the file name */
1240     name = MALLOC (char, ext - base_name + 1);
1241     if (!name)
1242     {
1243     ++errors;
1244     goto cleanup;
1245     }
1246    
1247     /* canonicalize the module name */
1248     {
1249     int i;
1250     for (i = 0; i < ext - base_name; ++i)
1251     {
1252     if (isalnum ((unsigned char)(base_name[i])))
1253     {
1254     name[i] = base_name[i];
1255     }
1256     else
1257     {
1258     name[i] = '_';
1259     }
1260     }
1261     name[ext - base_name] = LT_EOS_CHAR;
1262     }
1263    
1264     /* Before trawling through the filesystem in search of a module,
1265     check whether we are opening a preloaded module. */
1266     if (!dir)
1267     {
1268     const lt_dlvtable *vtable = lt_dlloader_find ("lt_preopen");
1269    
1270     if (vtable)
1271     {
1272     /* name + "." + libext + NULL */
1273 michael 1094 archive_name = MALLOC (char, LT_STRLEN (name) + strlen (libext) + 2);
1274 michael 945 *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1275    
1276     if ((*phandle == NULL) || (archive_name == NULL))
1277     {
1278     ++errors;
1279     goto cleanup;
1280     }
1281     newhandle = *phandle;
1282    
1283     /* Preloaded modules are always named according to their old
1284     archive name. */
1285     sprintf (archive_name, "%s.%s", name, libext);
1286    
1287     if (tryall_dlopen (&newhandle, archive_name, advise, vtable) == 0)
1288     {
1289     goto register_handle;
1290     }
1291    
1292     /* If we're still here, there was no matching preloaded module,
1293     so put things back as we found them, and continue searching. */
1294     FREE (*phandle);
1295     newhandle = NULL;
1296     }
1297     }
1298    
1299     /* If we are allowing only preloaded modules, and we didn't find
1300     anything yet, give up on the search here. */
1301     if (advise && advise->try_preload_only)
1302     {
1303     goto cleanup;
1304     }
1305    
1306     /* Check whether we are opening a libtool module (.la extension). */
1307     if (ext && streq (ext, archive_ext))
1308     {
1309     /* this seems to be a libtool module */
1310     FILE * file = 0;
1311     char * dlname = 0;
1312     char * old_name = 0;
1313     char * libdir = 0;
1314     char * deplibs = 0;
1315    
1316     /* if we can't find the installed flag, it is probably an
1317     installed libtool archive, produced with an old version
1318     of libtool */
1319     int installed = 1;
1320    
1321     /* Now try to open the .la file. If there is no directory name
1322     component, try to find it first in user_search_path and then other
1323     prescribed paths. Otherwise (or in any case if the module was not
1324     yet found) try opening just the module name as passed. */
1325     if (!dir)
1326     {
1327     const char *search_path = user_search_path;
1328    
1329     if (search_path)
1330     file = find_file (user_search_path, base_name, &dir);
1331    
1332     if (!file)
1333     {
1334     search_path = getenv (LTDL_SEARCHPATH_VAR);
1335     if (search_path)
1336     file = find_file (search_path, base_name, &dir);
1337     }
1338    
1339     #if defined(LT_MODULE_PATH_VAR)
1340     if (!file)
1341     {
1342     search_path = getenv (LT_MODULE_PATH_VAR);
1343     if (search_path)
1344     file = find_file (search_path, base_name, &dir);
1345     }
1346     #endif
1347     #if defined(LT_DLSEARCH_PATH)
1348     if (!file && *sys_dlsearch_path)
1349     {
1350     file = find_file (sys_dlsearch_path, base_name, &dir);
1351     }
1352     #endif
1353     }
1354 michael 1037 else
1355 michael 945 {
1356     file = fopen (attempt, LT_READTEXT_MODE);
1357     }
1358    
1359     /* If we didn't find the file by now, it really isn't there. Set
1360     the status flag, and bail out. */
1361     if (!file)
1362     {
1363     LT__SETERROR (FILE_NOT_FOUND);
1364     ++errors;
1365     goto cleanup;
1366     }
1367    
1368     /* read the .la file */
1369     if (parse_dotla_file(file, &dlname, &libdir, &deplibs,
1370     &old_name, &installed) != 0)
1371     ++errors;
1372    
1373     fclose (file);
1374    
1375     /* allocate the handle */
1376     *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1377     if (*phandle == 0)
1378     ++errors;
1379    
1380     if (errors)
1381     {
1382     FREE (dlname);
1383     FREE (old_name);
1384     FREE (libdir);
1385     FREE (deplibs);
1386     FREE (*phandle);
1387     goto cleanup;
1388     }
1389    
1390     assert (*phandle);
1391    
1392     if (load_deplibs (*phandle, deplibs) == 0)
1393     {
1394     newhandle = *phandle;
1395     /* find_module may replace newhandle */
1396     if (find_module (&newhandle, dir, libdir, dlname, old_name,
1397     installed, advise))
1398     {
1399     unload_deplibs (*phandle);
1400     ++errors;
1401     }
1402     }
1403     else
1404     {
1405     ++errors;
1406     }
1407    
1408     FREE (dlname);
1409     FREE (old_name);
1410     FREE (libdir);
1411     FREE (deplibs);
1412    
1413     if (errors)
1414     {
1415     FREE (*phandle);
1416     goto cleanup;
1417     }
1418    
1419     if (*phandle != newhandle)
1420     {
1421     unload_deplibs (*phandle);
1422     }
1423     }
1424     else
1425     {
1426     /* not a libtool module */
1427     *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle));
1428     if (*phandle == 0)
1429     {
1430     ++errors;
1431     goto cleanup;
1432     }
1433    
1434     newhandle = *phandle;
1435    
1436     /* If the module has no directory name component, try to find it
1437     first in user_search_path and then other prescribed paths.
1438     Otherwise (or in any case if the module was not yet found) try
1439     opening just the module name as passed. */
1440     if ((dir || (!find_handle (user_search_path, base_name,
1441     &newhandle, advise)
1442     && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
1443     &newhandle, advise)
1444     #if defined(LT_MODULE_PATH_VAR)
1445     && !find_handle (getenv (LT_MODULE_PATH_VAR), base_name,
1446     &newhandle, advise)
1447     #endif
1448     #if defined(LT_DLSEARCH_PATH)
1449     && !find_handle (sys_dlsearch_path, base_name,
1450     &newhandle, advise)
1451     #endif
1452     )))
1453     {
1454     if (tryall_dlopen (&newhandle, attempt, advise, 0) != 0)
1455     {
1456     newhandle = NULL;
1457     }
1458     }
1459    
1460     if (!newhandle)
1461     {
1462     FREE (*phandle);
1463     ++errors;
1464     goto cleanup;
1465     }
1466     }
1467    
1468     register_handle:
1469     MEMREASSIGN (*phandle, newhandle);
1470    
1471     if ((*phandle)->info.ref_count == 0)
1472     {
1473     (*phandle)->info.ref_count = 1;
1474     MEMREASSIGN ((*phandle)->info.name, name);
1475    
1476     (*phandle)->next = handles;
1477     handles = *phandle;
1478     }
1479    
1480     LT__SETERRORSTR (saved_error);
1481    
1482     cleanup:
1483     FREE (dir);
1484     FREE (attempt);
1485     FREE (name);
1486     if (!canonical) /* was MEMREASSIGNed */
1487     FREE (base_name);
1488     FREE (canonical);
1489     FREE (archive_name);
1490    
1491     return errors;
1492     }
1493    
1494    
1495 michael 1094 /* If the last error message stored was `FILE_NOT_FOUND', then return
1496 michael 945 non-zero. */
1497     static int
1498     file_not_found (void)
1499     {
1500     const char *error = 0;
1501    
1502     LT__GETERROR (error);
1503     if (error == LT__STRERROR (FILE_NOT_FOUND))
1504     return 1;
1505    
1506     return 0;
1507     }
1508    
1509    
1510     /* Unless FILENAME already bears a suitable library extension, then
1511     return 0. */
1512     static int
1513     has_library_ext (const char *filename)
1514     {
1515 michael 1094 const char * ext = 0;
1516 michael 945
1517     assert (filename);
1518    
1519     ext = strrchr (filename, '.');
1520    
1521     if (ext && ((streq (ext, archive_ext))
1522     #if defined(LT_MODULE_EXT)
1523     || (streq (ext, shlib_ext))
1524     #endif
1525     ))
1526     {
1527     return 1;
1528     }
1529    
1530     return 0;
1531     }
1532    
1533    
1534     /* Initialise and configure a user lt_dladvise opaque object. */
1535    
1536     int
1537     lt_dladvise_init (lt_dladvise *padvise)
1538     {
1539     lt_dladvise advise = (lt_dladvise) lt__zalloc (sizeof (struct lt__advise));
1540     *padvise = advise;
1541     return (advise ? 0 : 1);
1542     }
1543    
1544     int
1545     lt_dladvise_destroy (lt_dladvise *padvise)
1546     {
1547     if (padvise)
1548     FREE(*padvise);
1549     return 0;
1550     }
1551    
1552     int
1553     lt_dladvise_ext (lt_dladvise *padvise)
1554     {
1555     assert (padvise && *padvise);
1556     (*padvise)->try_ext = 1;
1557     return 0;
1558     }
1559    
1560     int
1561     lt_dladvise_resident (lt_dladvise *padvise)
1562     {
1563     assert (padvise && *padvise);
1564     (*padvise)->is_resident = 1;
1565     return 0;
1566     }
1567    
1568     int
1569     lt_dladvise_local (lt_dladvise *padvise)
1570     {
1571     assert (padvise && *padvise);
1572     (*padvise)->is_symlocal = 1;
1573     return 0;
1574     }
1575    
1576     int
1577     lt_dladvise_global (lt_dladvise *padvise)
1578     {
1579     assert (padvise && *padvise);
1580     (*padvise)->is_symglobal = 1;
1581     return 0;
1582     }
1583    
1584     int
1585     lt_dladvise_preload (lt_dladvise *padvise)
1586     {
1587     assert (padvise && *padvise);
1588     (*padvise)->try_preload_only = 1;
1589     return 0;
1590     }
1591    
1592     /* Libtool-1.5.x interface for loading a new module named FILENAME. */
1593     lt_dlhandle
1594     lt_dlopen (const char *filename)
1595     {
1596     return lt_dlopenadvise (filename, NULL);
1597     }
1598    
1599    
1600     /* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to
1601     open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT,
1602     and if a file is still not found try again with MODULE_EXT appended
1603     instead. */
1604     lt_dlhandle
1605     lt_dlopenext (const char *filename)
1606     {
1607     lt_dlhandle handle = 0;
1608     lt_dladvise advise;
1609    
1610     if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise))
1611     handle = lt_dlopenadvise (filename, advise);
1612    
1613     lt_dladvise_destroy (&advise);
1614     return handle;
1615     }
1616    
1617    
1618     lt_dlhandle
1619     lt_dlopenadvise (const char *filename, lt_dladvise advise)
1620     {
1621     lt_dlhandle handle = 0;
1622     int errors = 0;
1623 michael 1094 const char * saved_error = 0;
1624 michael 945
1625 michael 1094 LT__GETERROR (saved_error);
1626    
1627 michael 945 /* Can't have symbols hidden and visible at the same time! */
1628     if (advise && advise->is_symlocal && advise->is_symglobal)
1629     {
1630     LT__SETERROR (CONFLICTING_FLAGS);
1631     return 0;
1632     }
1633    
1634     if (!filename
1635     || !advise
1636     || !advise->try_ext
1637     || has_library_ext (filename))
1638     {
1639     /* Just incase we missed a code path in try_dlopen() that reports
1640     an error, but forgot to reset handle... */
1641     if (try_dlopen (&handle, filename, NULL, advise) != 0)
1642     return 0;
1643    
1644     return handle;
1645     }
1646     else if (filename && *filename)
1647     {
1648    
1649     /* First try appending ARCHIVE_EXT. */
1650     errors += try_dlopen (&handle, filename, archive_ext, advise);
1651    
1652     /* If we found FILENAME, stop searching -- whether we were able to
1653     load the file as a module or not. If the file exists but loading
1654     failed, it is better to return an error message here than to
1655     report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
1656     in the module search path. */
1657     if (handle || ((errors > 0) && !file_not_found ()))
1658     return handle;
1659    
1660     #if defined(LT_MODULE_EXT)
1661     /* Try appending SHLIB_EXT. */
1662 michael 1094 LT__SETERRORSTR (saved_error);
1663 michael 945 errors = try_dlopen (&handle, filename, shlib_ext, advise);
1664    
1665     /* As before, if the file was found but loading failed, return now
1666     with the current error message. */
1667     if (handle || ((errors > 0) && !file_not_found ()))
1668     return handle;
1669     #endif
1670     }
1671    
1672     /* Still here? Then we really did fail to locate any of the file
1673     names we tried. */
1674     LT__SETERROR (FILE_NOT_FOUND);
1675     return 0;
1676     }
1677    
1678    
1679     static int
1680     lt_argz_insert (char **pargz, size_t *pargz_len, char *before,
1681     const char *entry)
1682     {
1683     error_t error;
1684    
1685     /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz,
1686     pargz_len, NULL, entry) failed with EINVAL. */
1687     if (before)
1688     error = argz_insert (pargz, pargz_len, before, entry);
1689     else
1690     error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry));
1691    
1692     if (error)
1693     {
1694     switch (error)
1695     {
1696     case ENOMEM:
1697     LT__SETERROR (NO_MEMORY);
1698     break;
1699     default:
1700     LT__SETERROR (UNKNOWN);
1701     break;
1702     }
1703     return 1;
1704     }
1705    
1706     return 0;
1707     }
1708    
1709     static int
1710     lt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry)
1711     {
1712     char *before = 0;
1713    
1714     assert (pargz);
1715     assert (pargz_len);
1716     assert (entry && *entry);
1717    
1718     if (*pargz)
1719     while ((before = argz_next (*pargz, *pargz_len, before)))
1720     {
1721     int cmp = strcmp (entry, before);
1722    
1723     if (cmp < 0) break;
1724     if (cmp == 0) return 0; /* No duplicates! */
1725     }
1726    
1727     return lt_argz_insert (pargz, pargz_len, before, entry);
1728     }
1729    
1730     static int
1731     lt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam,
1732     struct dirent *dp)
1733     {
1734     char *buf = 0;
1735     size_t buf_len = 0;
1736     char *end = 0;
1737     size_t end_offset = 0;
1738     size_t dir_len = 0;
1739     int errors = 0;
1740    
1741     assert (pargz);
1742     assert (pargz_len);
1743     assert (dp);
1744    
1745     dir_len = LT_STRLEN (dirnam);
1746     end = dp->d_name + D_NAMLEN(dp);
1747    
1748     /* Ignore version numbers. */
1749     {
1750     char *p;
1751     for (p = end; p -1 > dp->d_name; --p)
1752     if (strchr (".0123456789", p[-1]) == 0)
1753     break;
1754    
1755     if (*p == '.')
1756     end = p;
1757     }
1758    
1759     /* Ignore filename extension. */
1760     {
1761     char *p;
1762     for (p = end -1; p > dp->d_name; --p)
1763     if (*p == '.')
1764     {
1765     end = p;
1766     break;
1767     }
1768     }
1769    
1770     /* Prepend the directory name. */
1771     end_offset = end - dp->d_name;
1772     buf_len = dir_len + 1+ end_offset;
1773     buf = MALLOC (char, 1+ buf_len);
1774     if (!buf)
1775     return ++errors;
1776    
1777     assert (buf);
1778    
1779     strcpy (buf, dirnam);
1780     strcat (buf, "/");
1781     strncat (buf, dp->d_name, end_offset);
1782     buf[buf_len] = LT_EOS_CHAR;
1783    
1784     /* Try to insert (in order) into ARGZ/ARGZ_LEN. */
1785     if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
1786     ++errors;
1787    
1788     FREE (buf);
1789    
1790     return errors;
1791     }
1792    
1793     static int
1794     list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len)
1795     {
1796     DIR *dirp = 0;
1797     int errors = 0;
1798    
1799     assert (dirnam && *dirnam);
1800     assert (pargz);
1801     assert (pargz_len);
1802     assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
1803    
1804     dirp = opendir (dirnam);
1805     if (dirp)
1806     {
1807     struct dirent *dp = 0;
1808    
1809     while ((dp = readdir (dirp)))
1810     if (dp->d_name[0] != '.')
1811     if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
1812     {
1813     ++errors;
1814     break;
1815     }
1816    
1817     closedir (dirp);
1818     }
1819     else
1820     ++errors;
1821    
1822     return errors;
1823     }
1824    
1825    
1826     /* If there are any files in DIRNAME, call the function passed in
1827     DATA1 (with the name of each file and DATA2 as arguments). */
1828     static int
1829     foreachfile_callback (char *dirname, void *data1, void *data2)
1830     {
1831     file_worker_func *func = *(file_worker_func **) data1;
1832    
1833     int is_done = 0;
1834     char *argz = 0;
1835     size_t argz_len = 0;
1836    
1837     if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
1838     goto cleanup;
1839     if (!argz)
1840     goto cleanup;
1841    
1842     {
1843     char *filename = 0;
1844     while ((filename = argz_next (argz, argz_len, filename)))
1845     if ((is_done = (*func) (filename, data2)))
1846     break;
1847     }
1848    
1849     cleanup:
1850     FREE (argz);
1851    
1852     return is_done;
1853     }
1854    
1855    
1856     /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
1857     with DATA. The filenames passed to FUNC would be suitable for
1858     passing to lt_dlopenext. The extensions are stripped so that
1859     individual modules do not generate several entries (e.g. libfoo.la,
1860     libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL,
1861     then the same directories that lt_dlopen would search are examined. */
1862     int
1863     lt_dlforeachfile (const char *search_path,
1864     int (*func) (const char *filename, void *data),
1865     void *data)
1866     {
1867     int is_done = 0;
1868     file_worker_func **fpptr = &func;
1869    
1870     if (search_path)
1871     {
1872     /* If a specific path was passed, search only the directories
1873     listed in it. */
1874     is_done = foreach_dirinpath (search_path, 0,
1875     foreachfile_callback, fpptr, data);
1876     }
1877     else
1878     {
1879     /* Otherwise search the default paths. */
1880     is_done = foreach_dirinpath (user_search_path, 0,
1881     foreachfile_callback, fpptr, data);
1882     if (!is_done)
1883     {
1884     is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0,
1885     foreachfile_callback, fpptr, data);
1886     }
1887    
1888     #if defined(LT_MODULE_PATH_VAR)
1889     if (!is_done)
1890     {
1891     is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0,
1892     foreachfile_callback, fpptr, data);
1893     }
1894     #endif
1895     #if defined(LT_DLSEARCH_PATH)
1896     if (!is_done && *sys_dlsearch_path)
1897     {
1898     is_done = foreach_dirinpath (sys_dlsearch_path, 0,
1899     foreachfile_callback, fpptr, data);
1900     }
1901     #endif
1902     }
1903    
1904     return is_done;
1905     }
1906    
1907     int
1908     lt_dlclose (lt_dlhandle handle)
1909     {
1910     lt_dlhandle cur, last;
1911     int errors = 0;
1912    
1913     /* check whether the handle is valid */
1914     last = cur = handles;
1915     while (cur && handle != cur)
1916     {
1917     last = cur;
1918     cur = cur->next;
1919     }
1920    
1921     if (!cur)
1922     {
1923     LT__SETERROR (INVALID_HANDLE);
1924     ++errors;
1925     goto done;
1926     }
1927    
1928     cur = handle;
1929     cur->info.ref_count--;
1930    
1931     /* Note that even with resident modules, we must track the ref_count
1932     correctly incase the user decides to reset the residency flag
1933     later (even though the API makes no provision for that at the
1934     moment). */
1935     if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur))
1936     {
1937     lt_user_data data = cur->vtable->dlloader_data;
1938    
1939     if (cur != handles)
1940     {
1941     last->next = cur->next;
1942     }
1943     else
1944     {
1945     handles = cur->next;
1946     }
1947    
1948     errors += cur->vtable->module_close (data, cur->module);
1949     errors += unload_deplibs (handle);
1950    
1951     /* It is up to the callers to free the data itself. */
1952     FREE (cur->interface_data);
1953    
1954     FREE (cur->info.filename);
1955     FREE (cur->info.name);
1956     FREE (cur);
1957    
1958     goto done;
1959     }
1960    
1961     if (LT_DLIS_RESIDENT (handle))
1962     {
1963     LT__SETERROR (CLOSE_RESIDENT_MODULE);
1964     ++errors;
1965     }
1966    
1967     done:
1968     return errors;
1969     }
1970    
1971     void *
1972     lt_dlsym (lt_dlhandle place, const char *symbol)
1973     {
1974     size_t lensym;
1975     char lsym[LT_SYMBOL_LENGTH];
1976     char *sym;
1977     void *address;
1978     lt_user_data data;
1979     lt_dlhandle handle;
1980    
1981     if (!place)
1982     {
1983     LT__SETERROR (INVALID_HANDLE);
1984     return 0;
1985     }
1986    
1987     handle = place;
1988    
1989     if (!symbol)
1990     {
1991     LT__SETERROR (SYMBOL_NOT_FOUND);
1992     return 0;
1993     }
1994    
1995     lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->vtable->sym_prefix)
1996     + LT_STRLEN (handle->info.name);
1997    
1998     if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
1999     {
2000     sym = lsym;
2001     }
2002     else
2003     {
2004     sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
2005     if (!sym)
2006     {
2007     LT__SETERROR (BUFFER_OVERFLOW);
2008     return 0;
2009     }
2010     }
2011    
2012     data = handle->vtable->dlloader_data;
2013     if (handle->info.name)
2014     {
2015     const char *saved_error;
2016    
2017     LT__GETERROR (saved_error);
2018    
2019     /* this is a libtool module */
2020     if (handle->vtable->sym_prefix)
2021     {
2022     strcpy(sym, handle->vtable->sym_prefix);
2023     strcat(sym, handle->info.name);
2024     }
2025     else
2026     {
2027     strcpy(sym, handle->info.name);
2028     }
2029    
2030     strcat(sym, "_LTX_");
2031     strcat(sym, symbol);
2032    
2033     /* try "modulename_LTX_symbol" */
2034     address = handle->vtable->find_sym (data, handle->module, sym);
2035     if (address)
2036     {
2037     if (sym != lsym)
2038     {
2039     FREE (sym);
2040     }
2041     return address;
2042     }
2043     LT__SETERRORSTR (saved_error);
2044     }
2045    
2046     /* otherwise try "symbol" */
2047     if (handle->vtable->sym_prefix)
2048     {
2049     strcpy(sym, handle->vtable->sym_prefix);
2050     strcat(sym, symbol);
2051     }
2052     else
2053     {
2054     strcpy(sym, symbol);
2055     }
2056    
2057     address = handle->vtable->find_sym (data, handle->module, sym);
2058     if (sym != lsym)
2059     {
2060     FREE (sym);
2061     }
2062    
2063     return address;
2064     }
2065    
2066     const char *
2067     lt_dlerror (void)
2068     {
2069     const char *error;
2070    
2071     LT__GETERROR (error);
2072     LT__SETERRORSTR (0);
2073    
2074 michael 1094 return error;
2075 michael 945 }
2076    
2077     static int
2078     lt_dlpath_insertdir (char **ppath, char *before, const char *dir)
2079     {
2080     int errors = 0;
2081     char *canonical = 0;
2082     char *argz = 0;
2083     size_t argz_len = 0;
2084    
2085     assert (ppath);
2086     assert (dir && *dir);
2087    
2088     if (canonicalize_path (dir, &canonical) != 0)
2089     {
2090     ++errors;
2091     goto cleanup;
2092     }
2093    
2094     assert (canonical && *canonical);
2095    
2096     /* If *PPATH is empty, set it to DIR. */
2097     if (*ppath == 0)
2098     {
2099     assert (!before); /* BEFORE cannot be set without PPATH. */
2100     assert (dir); /* Without DIR, don't call this function! */
2101    
2102     *ppath = lt__strdup (dir);
2103     if (*ppath == 0)
2104     ++errors;
2105    
2106     goto cleanup;
2107     }
2108    
2109     assert (ppath && *ppath);
2110    
2111     if (argzize_path (*ppath, &argz, &argz_len) != 0)
2112     {
2113     ++errors;
2114     goto cleanup;
2115     }
2116    
2117     /* Convert BEFORE into an equivalent offset into ARGZ. This only works
2118     if *PPATH is already canonicalized, and hence does not change length
2119     with respect to ARGZ. We canonicalize each entry as it is added to
2120     the search path, and don't call this function with (uncanonicalized)
2121     user paths, so this is a fair assumption. */
2122     if (before)
2123     {
2124     assert (*ppath <= before);
2125     assert ((int) (before - *ppath) <= (int) strlen (*ppath));
2126    
2127     before = before - *ppath + argz;
2128     }
2129    
2130     if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
2131     {
2132     ++errors;
2133     goto cleanup;
2134     }
2135    
2136     argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
2137     MEMREASSIGN(*ppath, argz);
2138    
2139     cleanup:
2140     FREE (argz);
2141     FREE (canonical);
2142    
2143     return errors;
2144     }
2145    
2146     int
2147     lt_dladdsearchdir (const char *search_dir)
2148     {
2149     int errors = 0;
2150    
2151     if (search_dir && *search_dir)
2152     {
2153     if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
2154     ++errors;
2155     }
2156    
2157     return errors;
2158     }
2159    
2160     int
2161     lt_dlinsertsearchdir (const char *before, const char *search_dir)
2162     {
2163     int errors = 0;
2164    
2165     if (before)
2166     {
2167     if ((before < user_search_path)
2168     || (before >= user_search_path + LT_STRLEN (user_search_path)))
2169     {
2170     LT__SETERROR (INVALID_POSITION);
2171     return 1;
2172     }
2173     }
2174    
2175     if (search_dir && *search_dir)
2176     {
2177     if (lt_dlpath_insertdir (&user_search_path,
2178     (char *) before, search_dir) != 0)
2179     {
2180     ++errors;
2181     }
2182     }
2183    
2184     return errors;
2185     }
2186    
2187     int
2188     lt_dlsetsearchpath (const char *search_path)
2189     {
2190     int errors = 0;
2191    
2192     FREE (user_search_path);
2193    
2194     if (!search_path || !LT_STRLEN (search_path))
2195     {
2196     return errors;
2197     }
2198    
2199     if (canonicalize_path (search_path, &user_search_path) != 0)
2200     ++errors;
2201    
2202     return errors;
2203     }
2204    
2205     const char *
2206     lt_dlgetsearchpath (void)
2207     {
2208     const char *saved_path;
2209    
2210     saved_path = user_search_path;
2211    
2212     return saved_path;
2213     }
2214    
2215     int
2216     lt_dlmakeresident (lt_dlhandle handle)
2217     {
2218     int errors = 0;
2219    
2220     if (!handle)
2221     {
2222     LT__SETERROR (INVALID_HANDLE);
2223     ++errors;
2224     }
2225     else
2226     {
2227     handle->info.is_resident = 1;
2228     }
2229    
2230     return errors;
2231     }
2232    
2233     int
2234     lt_dlisresident (lt_dlhandle handle)
2235     {
2236     if (!handle)
2237     {
2238     LT__SETERROR (INVALID_HANDLE);
2239     return -1;
2240     }
2241    
2242     return LT_DLIS_RESIDENT (handle);
2243     }
2244    
2245    
2246    
2247     /* --- MODULE INFORMATION --- */
2248    
2249     typedef struct {
2250     const char *id_string;
2251     lt_dlhandle_interface *iface;
2252     } lt__interface_id;
2253    
2254     lt_dlinterface_id
2255     lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface)
2256     {
2257     lt__interface_id *interface_id = (lt__interface_id *) lt__malloc (sizeof *interface_id);
2258    
2259     /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which
2260     can then be detected with lt_dlerror() if we return 0. */
2261     if (interface_id)
2262     {
2263     interface_id->id_string = lt__strdup (id_string);
2264     if (!interface_id->id_string)
2265     FREE (interface_id);
2266     else
2267     interface_id->iface = iface;
2268     }
2269    
2270     return (lt_dlinterface_id) interface_id;
2271     }
2272    
2273     void lt_dlinterface_free (lt_dlinterface_id key)
2274     {
2275     lt__interface_id *interface_id = (lt__interface_id *)key;
2276     FREE (interface_id->id_string);
2277     FREE (interface_id);
2278     }
2279    
2280     void *
2281     lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data)
2282     {
2283     int n_elements = 0;
2284     void *stale = (void *) 0;
2285     lt_dlhandle cur = handle;
2286     int i;
2287    
2288     if (cur->interface_data)
2289     while (cur->interface_data[n_elements].key)
2290     ++n_elements;
2291    
2292     for (i = 0; i < n_elements; ++i)
2293     {
2294     if (cur->interface_data[i].key == key)
2295     {
2296     stale = cur->interface_data[i].data;
2297     break;
2298     }
2299     }
2300    
2301     /* Ensure that there is enough room in this handle's interface_data
2302     array to accept a new element (and an empty end marker). */
2303     if (i == n_elements)
2304     {
2305     lt_interface_data *temp
2306     = REALLOC (lt_interface_data, cur->interface_data, 2+ n_elements);
2307    
2308     if (!temp)
2309     {
2310     stale = 0;
2311     goto done;
2312     }
2313    
2314     cur->interface_data = temp;
2315    
2316     /* We only need this if we needed to allocate a new interface_data. */
2317     cur->interface_data[i].key = key;
2318     cur->interface_data[1+ i].key = 0;
2319     }
2320    
2321     cur->interface_data[i].data = data;
2322    
2323     done:
2324     return stale;
2325     }
2326    
2327     void *
2328     lt_dlcaller_get_data (lt_dlinterface_id key, lt_dlhandle handle)
2329     {
2330     void *result = (void *) 0;
2331     lt_dlhandle cur = handle;
2332    
2333     /* Locate the index of the element with a matching KEY. */
2334     if (cur->interface_data)
2335     {
2336     int i;
2337     for (i = 0; cur->interface_data[i].key; ++i)
2338     {
2339     if (cur->interface_data[i].key == key)
2340     {
2341     result = cur->interface_data[i].data;
2342     break;
2343     }
2344     }
2345     }
2346    
2347     return result;
2348     }
2349    
2350     const lt_dlinfo *
2351     lt_dlgetinfo (lt_dlhandle handle)
2352     {
2353     if (!handle)
2354     {
2355     LT__SETERROR (INVALID_HANDLE);
2356     return 0;
2357     }
2358    
2359     return &(handle->info);
2360     }
2361    
2362    
2363     lt_dlhandle
2364     lt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place)
2365     {
2366     lt_dlhandle handle = place;
2367     lt__interface_id *iterator = (lt__interface_id *) iface;
2368    
2369     assert (iface); /* iface is a required argument */
2370    
2371     if (!handle)
2372     handle = handles;
2373     else
2374     handle = handle->next;
2375    
2376     /* advance while the interface check fails */
2377     while (handle && iterator->iface
2378     && ((*iterator->iface) (handle, iterator->id_string) != 0))
2379     {
2380     handle = handle->next;
2381     }
2382    
2383     return handle;
2384     }
2385    
2386    
2387     lt_dlhandle
2388     lt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name)
2389     {
2390     lt_dlhandle handle = 0;
2391    
2392     assert (iface); /* iface is a required argument */
2393    
2394     while ((handle = lt_dlhandle_iterate (iface, handle)))
2395     {
2396     lt_dlhandle cur = handle;
2397     if (cur && cur->info.name && streq (cur->info.name, module_name))
2398     break;
2399     }
2400    
2401     return handle;
2402     }
2403    
2404    
2405     int
2406     lt_dlhandle_map (lt_dlinterface_id iface,
2407     int (*func) (lt_dlhandle handle, void *data), void *data)
2408     {
2409     lt__interface_id *iterator = (lt__interface_id *) iface;
2410     lt_dlhandle cur = handles;
2411    
2412     assert (iface); /* iface is a required argument */
2413    
2414     while (cur)
2415     {
2416     int errorcode = 0;
2417    
2418     /* advance while the interface check fails */
2419     while (cur && iterator->iface
2420     && ((*iterator->iface) (cur, iterator->id_string) != 0))
2421     {
2422     cur = cur->next;
2423     }
2424    
2425     if ((errorcode = (*func) (cur, data)) != 0)
2426     return errorcode;
2427     }
2428    
2429     return 0;
2430     }

Properties

Name Value
svn:eol-style native