/[libtool]/libtool/libltdl/ltdl.c
ViewVC logotype

Diff of /libtool/libltdl/ltdl.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.134.2.1 by gary, Fri Jun 29 01:18:05 2001 UTC revision 1.134.2.2 by gary, Sun Sep 2 18:54:31 2001 UTC
# Line 29  Foundation, Inc., 59 Temple Place, Suite Line 29  Foundation, Inc., 59 Temple Place, Suite
29  #  include <config.h>  #  include <config.h>
30  #endif  #endif
31    
32    #if HAVE_UNISTD_H
33    #  include <unistd.h>
34    #endif
35    
36  #if HAVE_STDIO_H  #if HAVE_STDIO_H
37  #  include <stdio.h>  #  include <stdio.h>
38  #endif  #endif
# Line 57  Foundation, Inc., 59 Temple Place, Suite Line 61  Foundation, Inc., 59 Temple Place, Suite
61  #  include <memory.h>  #  include <memory.h>
62  #endif  #endif
63    
64    #if HAVE_ERRNO_H
65    #  include <errno.h>
66    #endif
67    
68    #if HAVE_DIRENT_H
69    #  include <dirent.h>
70    #  define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
71    #else
72    #  define dirent direct
73    #  define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
74    #  if HAVE_SYS_NDIR_H
75    #    include <sys/ndir.h>
76    #  endif
77    #  if HAVE_SYS_DIR_H
78    #    include <sys/dir.h>
79    #  endif
80    #  if HAVE_NDIR_H
81    #    include <ndir.h>
82    #  endif
83    #endif
84    
85    #if HAVE_ARGZ_H
86    #  include <argz.h>
87    #endif
88    
89    /* I have never seen a system without this:  */
90    #include <assert.h>
91    
92  #include "ltdl.h"  #include "ltdl.h"
93    
94    
# Line 85  Foundation, Inc., 59 Temple Place, Suite Line 117  Foundation, Inc., 59 Temple Place, Suite
117  /* --- MANIFEST CONSTANTS --- */  /* --- MANIFEST CONSTANTS --- */
118    
119    
120    /* Standard libltdl search path environment variable name  */
121    #undef  LTDL_SEARCHPATH_VAR
122    #define LTDL_SEARCHPATH_VAR     "LTDL_LIBRARY_PATH"
123    
124    /* Standard libtool archive file extension.  */
125    #undef  LTDL_ARCHIVE_EXT
126    #define LTDL_ARCHIVE_EXT        ".la"
127    
128  /* max. filename length */  /* max. filename length */
129  #ifndef LT_FILENAME_MAX  #ifndef LT_FILENAME_MAX
130  #  define LT_FILENAME_MAX       1024  #  define LT_FILENAME_MAX       1024
# Line 101  Foundation, Inc., 59 Temple Place, Suite Line 141  Foundation, Inc., 59 Temple Place, Suite
141    
142    
143    
 /* --- TYPE DEFINITIONS -- */  
   
   
 /* This type is used for the array of caller data sets in each handler. */  
 typedef struct {  
   lt_dlcaller_id        key;  
   lt_ptr                data;  
 } lt_caller_data;  
   
   
   
   
 /* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */  
   
   
 /* Extract the diagnostic strings from the error table macro in the same  
    order as the enumberated indices in ltdl.h. */  
   
 static const char *lt_dlerror_strings[] =  
   {  
 #define LT_ERROR(name, diagnostic)      (diagnostic),  
     lt_dlerror_table  
 #undef LT_ERROR  
   
     0  
   };  
   
 /* This structure is used for the list of registered loaders. */  
 struct lt_dlloader {  
   struct lt_dlloader   *next;  
   const char           *loader_name;    /* identifying name for each loader */  
   const char           *sym_prefix;     /* prefix for symbols */  
   lt_module_open       *module_open;  
   lt_module_close      *module_close;  
   lt_find_sym          *find_sym;  
   lt_dlloader_exit     *dlloader_exit;  
   lt_user_data          dlloader_data;  
 };  
   
 struct lt_dlhandle_struct {  
   struct lt_dlhandle_struct   *next;  
   lt_dlloader          *loader;         /* dlopening interface */  
   lt_dlinfo             info;  
   int                   depcount;       /* number of dependencies */  
   lt_dlhandle          *deplibs;        /* dependencies */  
   lt_module             module;         /* system module handle */  
   lt_ptr                system;         /* system specific data */  
   lt_caller_data       *caller_data;    /* per caller associated data */  
   int                   flags;          /* various boolean stats */  
 };  
   
 /* Various boolean flags can be stored in the flags field of an  
    lt_dlhandle_struct... */  
 #define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))  
 #define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))  
   
 #define LT_DLRESIDENT_FLAG          (0x01 << 0)  
 /* ...add more flags here... */  
   
 #define LT_DLIS_RESIDENT(handle)    LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)  
   
   
 #define LT_DLSTRERROR(name)     lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]  
   
 static  const char      objdir[]                = LTDL_OBJDIR;  
 #ifdef  LTDL_SHLIB_EXT  
 static  const char      shlib_ext[]             = LTDL_SHLIB_EXT;  
 #endif  
 #ifdef  LTDL_SYSSEARCHPATH  
 static  const char      sys_search_path[]       = LTDL_SYSSEARCHPATH;  
 #endif  
   
   
   
   
 /* --- MUTEX LOCKING --- */  
   
   
 /* Macros to make it easier to run the lock functions only if they have  
    been registered.  The reason for the complicated lock macro is to  
    ensure that the stored error message from the last error is not  
    accidentally erased if the current function doesn't generate an  
    error of its own.  */  
 #define MUTEX_LOCK()                            LT_STMT_START { \  
         if (mutex_lock) (*mutex_lock)();        } LT_STMT_END  
 #define MUTEX_UNLOCK()                          LT_STMT_START { \  
         if (mutex_unlock) (*mutex_unlock)();    } LT_STMT_END  
 #define MUTEX_SETERROR(errormsg)                LT_STMT_START { \  
         if (mutex_seterror) (*mutex_seterror) (errormsg);       \  
         else last_error = (errormsg);           } LT_STMT_END  
 #define MUTEX_GETERROR(errormsg)                LT_STMT_START { \  
         if (mutex_seterror) errormsg = (*mutex_geterror)();     \  
         else (errormsg) = last_error;           } LT_STMT_END  
   
 /* The mutex functions stored here are global, and are necessarily the  
    same for all threads that wish to share access to libltdl.  */  
 static  lt_dlmutex_lock     *mutex_lock     = 0;  
 static  lt_dlmutex_unlock   *mutex_unlock   = 0;  
 static  lt_dlmutex_seterror *mutex_seterror = 0;  
 static  lt_dlmutex_geterror *mutex_geterror = 0;  
 static  const char          *last_error     = 0;  
   
   
 /* Either set or reset the mutex functions.  Either all the arguments must  
    be valid functions, or else all can be NULL to turn off locking entirely.  
    The registered functions should be manipulating a static global lock  
    from the lock() and unlock() callbacks, which needs to be reentrant.  */  
 int  
 lt_dlmutex_register (lock, unlock, seterror, geterror)  
      lt_dlmutex_lock *lock;  
      lt_dlmutex_unlock *unlock;  
      lt_dlmutex_seterror *seterror;  
      lt_dlmutex_geterror *geterror;  
 {  
   lt_dlmutex_unlock *old_unlock = unlock;  
   int                errors     = 0;  
   
   /* Lock using the old lock() callback, if any.  */  
   MUTEX_LOCK ();  
   
   if ((lock && unlock && seterror && geterror)  
       || !(lock || unlock || seterror || geterror))  
     {  
       mutex_lock     = lock;  
       mutex_unlock   = unlock;  
       mutex_geterror = geterror;  
     }  
   else  
     {  
       MUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));  
       ++errors;  
     }  
   
   /* Use the old unlock() callback we saved earlier, if any.  Otherwise  
      record any errors using internal storage.  */  
   if (old_unlock)  
     (*old_unlock) ();  
   
   /* Return the number of errors encountered during the execution of  
      this function.  */  
   return errors;  
 }  
   
   
   
   
144  /* --- MEMORY HANDLING --- */  /* --- MEMORY HANDLING --- */
145    
146    
147  LT_GLOBAL_DATA    lt_ptr        (*lt_dlmalloc)  LT_PARAMS((size_t size))  /* These are the functions used internally.  In addition to making
148                                      = (lt_ptr (*) LT_PARAMS((size_t))) malloc;     use of the associated function pointers above, they also perform
149  LT_GLOBAL_DATA    void          (*lt_dlfree)    LT_PARAMS((lt_ptr ptr))     error handling.  */
150                                      = (void (*) LT_PARAMS((lt_ptr))) free;  static char   *lt_estrdup       LT_PARAMS((const char *str));
151    static lt_ptr lt_emalloc        LT_PARAMS((size_t size));
152  static            lt_ptr        rpl_realloc     LT_PARAMS((lt_ptr ptr,  static lt_ptr lt_erealloc       LT_PARAMS((lt_ptr addr, size_t size));
153                                                             size_t size));  
154    static lt_ptr rpl_realloc       LT_PARAMS((lt_ptr ptr, size_t size));
155    
156    /* These are the pointers that can be changed by the caller:  */
157    LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc)    LT_PARAMS((size_t size))
158                            = (lt_ptr (*) LT_PARAMS((size_t))) malloc;
159    LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc)   LT_PARAMS((lt_ptr ptr, size_t size))
160                            = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc;
161    LT_GLOBAL_DATA void   (*lt_dlfree)      LT_PARAMS((lt_ptr ptr))
162                            = (void (*) LT_PARAMS((lt_ptr))) free;
163    
164    /* The following macros reduce the amount of typing needed to cast
165       assigned memory.  */
166  #define LT_DLMALLOC(tp, n)      ((tp *) lt_dlmalloc ((n) * sizeof(tp)))  #define LT_DLMALLOC(tp, n)      ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
167  #define LT_DLREALLOC(tp, p, n)  ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))  #define LT_DLREALLOC(tp, p, n)  ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))
168  #define LT_DLFREE(p)                                            \  #define LT_DLFREE(p)                                            \
169          LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END          LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
170    
171    #define LT_EMALLOC(tp, n)       ((tp *) lt_emalloc ((n) * sizeof(tp)))
172    #define LT_EREALLOC(tp, p, n)   ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
173    
174  #define LT_DLMEM_REASSIGN(p, q)                 LT_STMT_START { \  #define LT_DLMEM_REASSIGN(p, q)                 LT_STMT_START { \
175          if ((p) != (q)) { lt_dlfree (p); (p) = (q); }           \          if ((p) != (q)) { lt_dlfree (p); (p) = (q); (q) = 0; }  \
176                                                  } LT_STMT_END                                                  } LT_STMT_END
177    
   
   
 /* --- ERROR MESSAGES --- */  
   
   
 static  const char    **user_error_strings      = 0;  
 static  int             errorcount              = LT_ERROR_MAX;  
   
 int  
 lt_dladderror (diagnostic)  
      const char *diagnostic;  
 {  
   int           index    = 0;  
   int           result   = -1;  
   const char  **temp     = (const char **) 0;  
   
   MUTEX_LOCK ();  
   
   index  = errorcount - LT_ERROR_MAX;  
   temp = LT_DLREALLOC (const char *, user_error_strings, 1 + index);  
   if (temp == 0)  
     {  
       MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  
     }  
   else  
     {  
       user_error_strings        = temp;  
       user_error_strings[index] = diagnostic;  
       result                    = errorcount++;  
     }  
   
   MUTEX_UNLOCK ();  
   
   return result;  
 }  
   
 int  
 lt_dlseterror (index)  
      int index;  
 {  
   int           errors   = 0;  
   
   MUTEX_LOCK ();  
   
   if (index >= errorcount || index < 0)  
     {  
       /* Ack!  Error setting the error message! */  
       MUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));  
       ++errors;  
     }  
   else if (index < LT_ERROR_MAX)  
     {  
       /* No error setting the error message! */  
       MUTEX_SETERROR (lt_dlerror_strings[errorcount]);  
     }  
   else  
     {  
       /* No error setting the error message! */  
       MUTEX_SETERROR (user_error_strings[errorcount - LT_ERROR_MAX]);  
     }  
   
   MUTEX_UNLOCK ();  
   
   return errors;  
 }  
   
   
   
178    
179  /* --- REPLACEMENT FUNCTIONS --- */  /* --- REPLACEMENT FUNCTIONS --- */
180    
# Line 342  lt_dlseterror (index) Line 182  lt_dlseterror (index)
182  #undef strdup  #undef strdup
183  #define strdup rpl_strdup  #define strdup rpl_strdup
184    
185  static char *  static char *strdup LT_PARAMS((const char *str));
186    
187    char *
188  strdup(str)  strdup(str)
189       const char *str;       const char *str;
190  {  {
# Line 366  strdup(str) Line 208  strdup(str)
208  #undef strcmp  #undef strcmp
209  #define strcmp rpl_strcmp  #define strcmp rpl_strcmp
210    
211  static int  static int strcmp LT_PARAMS((const char *str1, const char *str2));
212    
213    int
214  strcmp (str1, str2)  strcmp (str1, str2)
215       const char *str1;       const char *str1;
216       const char *str2;       const char *str2;
# Line 396  strcmp (str1, str2) Line 240  strcmp (str1, str2)
240  #  else  #  else
241  #    define strchr rpl_strchr  #    define strchr rpl_strchr
242    
243  static const char*  static const char *strchr LT_PARAMS((const char *str, int ch));
244    
245    const char*
246  strchr(str, ch)  strchr(str, ch)
247       const char *str;       const char *str;
248       int ch;       int ch;
249  {  {
250    const char *p;    const char *p;
251    
252    for (p = str; *p != (char)ch && *p != '\0'; ++p)    for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p)
253      /*NOWORK*/;      /*NOWORK*/;
254    
255    return (*p == (char)ch) ? p : 0;    return (*p == (char)ch) ? p : 0;
# Line 412  strchr(str, ch) Line 258  strchr(str, ch)
258  #  endif  #  endif
259  #endif /* !HAVE_STRCHR */  #endif /* !HAVE_STRCHR */
260    
261    
262  #if ! HAVE_STRRCHR  #if ! HAVE_STRRCHR
263    
264  #  if HAVE_RINDEX  #  if HAVE_RINDEX
# Line 419  strchr(str, ch) Line 266  strchr(str, ch)
266  #  else  #  else
267  #    define strrchr rpl_strrchr  #    define strrchr rpl_strrchr
268    
269  static const char*  static const char *strrchr LT_PARAMS((const char *str, int ch));
270    
271    const char*
272  strrchr(str, ch)  strrchr(str, ch)
273       const char *str;       const char *str;
274       int ch;       int ch;
275  {  {
276    const char *p, *q = 0;    const char *p, *q = 0;
277    
278    for (p = str; *p != '\0'; ++p)    for (p = str; *p != LT_EOS_CHAR; ++p)
279      {      {
280        if (*p == (char) ch)        if (*p == (char) ch)
281          {          {
# Line 441  strrchr(str, ch) Line 290  strrchr(str, ch)
290  #endif  #endif
291    
292  /* NOTE:  Neither bcopy nor the memcpy implementation below can  /* NOTE:  Neither bcopy nor the memcpy implementation below can
293            reliably handle copying in overlapping areas of memory, so            reliably handle copying in overlapping areas of memory.  Use
294            do not rely on this behaviour when invoking memcpy later.  */            memmove (for which there is a fallback implmentation below)
295              if you need that behaviour.  */
296  #if ! HAVE_MEMCPY  #if ! HAVE_MEMCPY
297    
298  #  if HAVE_BCOPY  #  if HAVE_BCOPY
# Line 450  strrchr(str, ch) Line 300  strrchr(str, ch)
300  #  else  #  else
301  #    define memcpy rpl_memcpy  #    define memcpy rpl_memcpy
302    
303  static char *  static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
304    
305    lt_ptr
306  memcpy (dest, src, size)  memcpy (dest, src, size)
307       char *dest;       lt_ptr dest;
308       const char *src;       const lt_ptr src;
309       size_t size;       size_t size;
310  {  {
311    size_t i = 0;    size_t i = 0;
# Line 466  memcpy (dest, src, size) Line 318  memcpy (dest, src, size)
318    return dest;    return dest;
319  }  }
320    
321  #  endif  #  endif /* !HAVE_BCOPY */
322  #endif  #endif   /* !HAVE_MEMCPY */
323    
324    #if ! HAVE_MEMMOVE
325    #  define memmove rpl_memmove
326    
327    static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
328    
329    lt_ptr
330    memmove (dest, src, size)
331         lt_ptr dest;
332         const lt_ptr src;
333         size_t size;
334    {
335      size_t i;
336    
337      if (dest < src)
338        for (i = 0; i < size; ++i)
339          {
340            dest[i] = src[i];
341          }
342      else if (dest > src)
343        for (i = size -1; i >= 0; --i)
344          {
345            dest[i] = src[i];
346          }
347    
348      return dest;
349    }
350    
351    #endif /* !HAVE_MEMMOVE */
352    
353    
354  /* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,  /* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
355      ``realloc is not entirely portable''      ``realloc is not entirely portable''
# Line 475  memcpy (dest, src, size) Line 357  memcpy (dest, src, size)
357     burdening them with an lt_dlrealloc function pointer to maintain.     burdening them with an lt_dlrealloc function pointer to maintain.
358     Instead implement our own version (with known boundary conditions)     Instead implement our own version (with known boundary conditions)
359     using lt_dlmalloc and lt_dlfree. */     using lt_dlmalloc and lt_dlfree. */
360  static lt_ptr  
361  rpl_realloc (ptr, size)  #undef realloc
362    #define realloc rpl_realloc
363    
364    lt_ptr
365    realloc (ptr, size)
366       lt_ptr ptr;       lt_ptr ptr;
367       size_t size;       size_t size;
368  {  {
369    if (size < 1)    if (size <= 0)
370      {      {
371        /* For zero or less bytes, free the original memory */        /* For zero or less bytes, free the original memory */
372        if (ptr != 0)        if (ptr != 0)
# Line 513  rpl_realloc (ptr, size) Line 399  rpl_realloc (ptr, size)
399  }  }
400    
401    
402    #if ! HAVE_ARGZ_APPEND
403    #  define argz_append rpl_argz_append
404    
405    static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len,
406                                            const char *buf, size_t buf_len));
407    
408    error_t
409    argz_append (pargz, pargz_len, buf, buf_len)
410         char **pargz;
411         size_t *pargz_len;
412         const char *buf;
413         size_t buf_len;
414    {
415      size_t argz_len;
416      char  *argz;
417    
418      assert (pargz);
419      assert (pargz_len);
420      assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
421    
422      /* If nothing needs to be appended, no more work is required.  */
423      if (buf_len == 0)
424        return 0;
425    
426      /* Ensure there is enough room to append BUF_LEN.  */
427      argz_len = *pargz_len + buf_len;
428      argz = LT_DLREALLOC (char, *pargz, argz_len);
429      if (!argz)
430        return ENOMEM;
431    
432      /* Copy characters from BUF after terminating '\0' in ARGZ.  */
433      memcpy (argz + *pargz_len, buf, buf_len);
434    
435      /* Assign new values.  */
436      *pargz = argz;
437      *pargz_len = argz_len;
438    
439      return 0;
440    }
441    #endif /* !HAVE_ARGZ_APPEND */
442    
443    
444    #if ! HAVE_ARGZ_CREATE_SEP
445    #  define argz_create_sep rpl_argz_create_sep
446    
447    static error_t argz_create_sep LT_PARAMS((const char *str, int delim,
448                                                char **pargz, size_t *pargz_len));
449    
450    error_t
451    argz_create_sep (str, delim, pargz, pargz_len)
452         const char *str;
453         int delim;
454         char **pargz;
455         size_t *pargz_len;
456    {
457      size_t argz_len;
458      char *argz = 0;
459    
460      assert (str);
461      assert (pargz);
462      assert (pargz_len);
463    
464      /* Make a copy of STR, but replacing each occurence of
465         DELIM with '\0'.  */
466      argz_len = 1+ LT_STRLEN (str);
467      if (argz_len)
468        {
469          const char *p;
470          char *q;
471    
472          argz = LT_DLMALLOC (char, argz_len);
473          if (!argz)
474            return ENOMEM;
475    
476          for (p = str, q = argz; *p != LT_EOS_CHAR; ++p)
477            {
478              if (*p == delim)
479                {
480                  /* Ignore leading delimiters, and fold consecutive
481                     delimiters in STR into a single '\0' in ARGZ.  */
482                  if ((q > argz) && (q[-1] != LT_EOS_CHAR))
483                    *q++ = LT_EOS_CHAR;
484                  else
485                    --argz_len;
486                }
487              else
488                *q++ = *p;
489            }
490          /* Copy terminating LT_EOS_CHAR.  */
491          *q = *p;
492        }
493    
494      /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory.  */
495      if (!argz_len)
496        LT_DLFREE (argz);
497    
498      /* Assign new values.  */
499      *pargz = argz;
500      *pargz_len = argz_len;
501    
502      return 0;
503    }
504    #endif /* !HAVE_ARGZ_CREATE_SEP */
505    
506    
507    #if ! HAVE_ARGZ_INSERT
508    #  define argz_insert rpl_argz_insert
509    
510    static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len,
511                                            char *before, const char *entry));
512    
513    error_t
514    argz_insert (pargz, pargz_len, before, entry)
515         char **pargz;
516         size_t *pargz_len;
517         char *before;
518         const char *entry;
519    {
520      assert (pargz);
521      assert (pargz_len);
522      assert (entry && *entry);
523    
524      /* Either PARGZ/PARGZ_LEN is empty and BEFORE is NULL,
525         or BEFORE points into an address within the ARGZ vector.  */
526      assert ((!*pargz && !*pargz_len && !before)
527              || ((*pargz <= before) && (before < (*pargz + *pargz_len))));
528    
529      /* No BEFORE address indicates ENTRY should be inserted after the
530         current last element.  */
531      if (!before)
532        return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry));
533    
534      /* This probably indicates a programmer error, but to preserve
535         semantics, scan back to the start of an entry if BEFORE points
536         into the middle of it.  */
537      while ((before >= *pargz) && (before[-1] != LT_EOS_CHAR))
538        --before;
539    
540      {
541        size_t entry_len    = 1+ LT_STRLEN (entry);
542        size_t argz_len     = *pargz_len + entry_len;
543        size_t offset       = before - *pargz;
544        char   *argz        = LT_DLREALLOC (char, *pargz, argz_len);
545    
546        if (!argz)
547          return ENOMEM;
548    
549        /* Make BEFORE point to the equivalent offset in ARGZ that it
550           used to have in *PARGZ incase realloc() moved the block.  */
551        before = argz + offset;
552    
553        /* Move the ARGZ entries starting at BEFORE up into the new
554           space at the end -- making room to copy ENTRY into the
555           resulting gap.  */
556        memmove (before + entry_len, before, *pargz_len - offset);
557        memcpy  (before, entry, entry_len);
558    
559        /* Assign new values.  */
560        *pargz = argz;
561        *pargz_len = argz_len;
562      }
563    
564      return 0;
565    }
566    #endif /* !HAVE_ARGZ_INSERT */
567    
568    
569    #if ! HAVE_ARGZ_NEXT
570    #  define argz_next rpl_argz_next
571    
572    static char *argz_next LT_PARAMS((char *argz, size_t argz_len,
573                                        const char *entry));
574    
575    char *
576    argz_next (argz, argz_len, entry)
577         char *argz;
578         size_t argz_len;
579         const char *entry;
580    {
581      assert ((argz && argz_len) || (!argz && !argz_len));
582    
583      if (entry)
584        {
585          /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
586             within the ARGZ vector.  */
587          assert ((!argz && !argz_len)
588                  || ((argz <= entry) && (entry < (argz + argz_len))));
589    
590          /* Move to the char immediately after the terminating
591             '\0' of ENTRY.  */
592          entry = 1+ strchr (entry, LT_EOS_CHAR);
593    
594          /* Return either the new ENTRY, or else NULL if ARGZ is
595             exhausted.  */
596          return (entry >= argz + argz_len) ? 0 : (char *) entry;
597        }
598      else
599        {
600          /* This should probably be flagged as a programmer error,
601             since starting an argz_next loop with the iterator set
602             to ARGZ is safer.  To preserve semantics, handle the NULL
603             case by returning the start of ARGZ (if any).  */
604          if (argz_len > 0)
605            return argz;
606          else
607            return 0;
608        }
609    }
610    #endif /* !HAVE_ARGZ_NEXT */
611    
612    
613    
614    #if ! HAVE_ARGZ_STRINGIFY
615    #  define argz_stringify rpl_argz_stringify
616    
617    static void argz_stringify LT_PARAMS((char *argz, size_t argz_len,
618                                           int sep));
619    
620    void
621    argz_stringify (argz, argz_len, sep)
622         char *argz;
623         size_t argz_len;
624         int sep;
625    {
626      assert ((argz && argz_len) || (!argz && !argz_len));
627    
628      if (sep)
629        {
630          --argz_len;               /* don't stringify the terminating EOS */
631          while (--argz_len > 0)
632            {
633              if (argz[argz_len] == LT_EOS_CHAR)
634                argz[argz_len] = sep;
635            }
636        }
637    }
638    #endif /* !HAVE_ARGZ_STRINGIFY */
639    
640    
641    
642    
643    /* --- TYPE DEFINITIONS -- */
644    
645    
646    /* This type is used for the array of caller data sets in each handler. */
647    typedef struct {
648      lt_dlcaller_id        key;
649      lt_ptr                data;
650    } lt_caller_data;
651    
652    
653    
654    
655    /* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */
656    
657    
658    /* Extract the diagnostic strings from the error table macro in the same
659       order as the enumerated indices in ltdl.h. */
660    
661    static const char *lt_dlerror_strings[] =
662      {
663    #define LT_ERROR(name, diagnostic)      (diagnostic),
664        lt_dlerror_table
665    #undef LT_ERROR
666    
667        0
668      };
669    
670    /* This structure is used for the list of registered loaders. */
671    struct lt_dlloader {
672      struct lt_dlloader   *next;
673      const char           *loader_name;    /* identifying name for each loader */
674      const char           *sym_prefix;     /* prefix for symbols */
675      lt_module_open       *module_open;
676      lt_module_close      *module_close;
677      lt_find_sym          *find_sym;
678      lt_dlloader_exit     *dlloader_exit;
679      lt_user_data          dlloader_data;
680    };
681    
682    struct lt_dlhandle_struct {
683      struct lt_dlhandle_struct   *next;
684      lt_dlloader          *loader;         /* dlopening interface */
685      lt_dlinfo             info;
686      int                   depcount;       /* number of dependencies */
687      lt_dlhandle          *deplibs;        /* dependencies */
688      lt_module             module;         /* system module handle */
689      lt_ptr                system;         /* system specific data */
690      lt_caller_data       *caller_data;    /* per caller associated data */
691      int                   flags;          /* various boolean stats */
692    };
693    
694    /* Various boolean flags can be stored in the flags field of an
695       lt_dlhandle_struct... */
696    #define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag))
697    #define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag))
698    
699    #define LT_DLRESIDENT_FLAG          (0x01 << 0)
700    /* ...add more flags here... */
701    
702    #define LT_DLIS_RESIDENT(handle)    LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG)
703    
704    
705    #define LT_DLSTRERROR(name)     lt_dlerror_strings[LT_CONC(LT_ERROR_,name)]
706    
707    static  const char      objdir[]                = LTDL_OBJDIR;
708    static  const char      archive_ext[]           = LTDL_ARCHIVE_EXT;
709    #ifdef  LTDL_SHLIB_EXT
710    static  const char      shlib_ext[]             = LTDL_SHLIB_EXT;
711    #endif
712    #ifdef  LTDL_SYSSEARCHPATH
713    static  const char      sys_search_path[]       = LTDL_SYSSEARCHPATH;
714    #endif
715    
716    
717    
718    
719    /* --- MUTEX LOCKING --- */
720    
721    
722    /* Macros to make it easier to run the lock functions only if they have
723       been registered.  The reason for the complicated lock macro is to
724       ensure that the stored error message from the last error is not
725       accidentally erased if the current function doesn't generate an
726       error of its own.  */
727    #define LT_DLMUTEX_LOCK()                       LT_STMT_START { \
728            if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)();    \
729                                                    } LT_STMT_END
730    #define LT_DLMUTEX_UNLOCK()                     LT_STMT_START { \
731            if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\
732                                                    } LT_STMT_END
733    #define LT_DLMUTEX_SETERROR(errormsg)           LT_STMT_START { \
734            if (lt_dlmutex_seterror_func)                           \
735                    (*lt_dlmutex_seterror_func) (errormsg);         \
736            else    lt_dllast_error = (errormsg);   } LT_STMT_END
737    #define LT_DLMUTEX_GETERROR(errormsg)           LT_STMT_START { \
738            if (lt_dlmutex_seterror_func)                           \
739                    (errormsg) = (*lt_dlmutex_geterror_func) ();    \
740            else    (errormsg) = lt_dllast_error;   } LT_STMT_END
741    
742    /* The mutex functions stored here are global, and are necessarily the
743       same for all threads that wish to share access to libltdl.  */
744    static  lt_dlmutex_lock     *lt_dlmutex_lock_func     = 0;
745    static  lt_dlmutex_unlock   *lt_dlmutex_unlock_func   = 0;
746    static  lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0;
747    static  lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0;
748    static  const char          *lt_dllast_error          = 0;
749    
750    
751    /* Either set or reset the mutex functions.  Either all the arguments must
752       be valid functions, or else all can be NULL to turn off locking entirely.
753       The registered functions should be manipulating a static global lock
754       from the lock() and unlock() callbacks, which needs to be reentrant.  */
755    int
756    lt_dlmutex_register (lock, unlock, seterror, geterror)
757         lt_dlmutex_lock *lock;
758         lt_dlmutex_unlock *unlock;
759         lt_dlmutex_seterror *seterror;
760         lt_dlmutex_geterror *geterror;
761    {
762      lt_dlmutex_unlock *old_unlock = unlock;
763      int                errors     = 0;
764    
765      /* Lock using the old lock() callback, if any.  */
766      LT_DLMUTEX_LOCK ();
767    
768      if ((lock && unlock && seterror && geterror)
769          || !(lock || unlock || seterror || geterror))
770        {
771          lt_dlmutex_lock_func     = lock;
772          lt_dlmutex_unlock_func   = unlock;
773          lt_dlmutex_geterror_func = geterror;
774        }
775      else
776        {
777          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS));
778          ++errors;
779        }
780    
781      /* Use the old unlock() callback we saved earlier, if any.  Otherwise
782         record any errors using internal storage.  */
783      if (old_unlock)
784        (*old_unlock) ();
785    
786      /* Return the number of errors encountered during the execution of
787         this function.  */
788      return errors;
789    }
790    
791    
792    
793    
794    /* --- ERROR HANDLING --- */
795    
796    
797    static  const char    **user_error_strings      = 0;
798    static  int             errorcount              = LT_ERROR_MAX;
799    
800    int
801    lt_dladderror (diagnostic)
802         const char *diagnostic;
803    {
804      int           errindex = 0;
805      int           result   = -1;
806      const char  **temp     = (const char **) 0;
807    
808      assert (diagnostic);
809    
810      LT_DLMUTEX_LOCK ();
811    
812      errindex = errorcount - LT_ERROR_MAX;
813      temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex);
814      if (temp)
815        {
816          user_error_strings                = temp;
817          user_error_strings[errindex]      = diagnostic;
818          result                            = errorcount++;
819        }
820    
821      LT_DLMUTEX_UNLOCK ();
822    
823      return result;
824    }
825    
826    int
827    lt_dlseterror (errindex)
828         int errindex;
829    {
830      int           errors   = 0;
831    
832      LT_DLMUTEX_LOCK ();
833    
834      if (errindex >= errorcount || errindex < 0)
835        {
836          /* Ack!  Error setting the error message! */
837          LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE));
838          ++errors;
839        }
840      else if (errindex < LT_ERROR_MAX)
841        {
842          /* No error setting the error message! */
843          LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]);
844        }
845      else
846        {
847          /* No error setting the error message! */
848          LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]);
849        }
850    
851      LT_DLMUTEX_UNLOCK ();
852    
853      return errors;
854    }
855    
856    lt_ptr
857    lt_emalloc (size)
858         size_t size;
859    {
860      lt_ptr mem = lt_dlmalloc (size);
861      if (size && !mem)
862        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
863      return mem;
864    }
865    
866    lt_ptr
867    lt_erealloc (addr, size)
868         lt_ptr addr;
869         size_t size;
870    {
871      lt_ptr mem = realloc (addr, size);
872      if (size && !mem)
873        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
874      return mem;
875    }
876    
877    char *
878    lt_estrdup (str)
879         const char *str;
880    {
881      char *dup = strdup (str);
882      if (LT_STRLEN (str) && !dup)
883        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
884      return dup;
885    }
886    
887    
888    
889    
890  /* --- DLOPEN() INTERFACE LOADER --- */  /* --- DLOPEN() INTERFACE LOADER --- */
# Line 584  sys_dl_open (loader_data, filename) Line 956  sys_dl_open (loader_data, filename)
956    
957    if (!module)    if (!module)
958      {      {
959        MUTEX_SETERROR (DLERROR (CANNOT_OPEN));        LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN));
960      }      }
961    
962    return module;    return module;
# Line 599  sys_dl_close (loader_data, module) Line 971  sys_dl_close (loader_data, module)
971    
972    if (dlclose (module) != 0)    if (dlclose (module) != 0)
973      {      {
974        MUTEX_SETERROR (DLERROR (CANNOT_CLOSE));        LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE));
975        ++errors;        ++errors;
976      }      }
977    
# Line 616  sys_dl_sym (loader_data, module, symbol) Line 988  sys_dl_sym (loader_data, module, symbol)
988    
989    if (!address)    if (!address)
990      {      {
991        MUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));        LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND));
992      }      }
993    
994    return address;    return address;
# Line 693  sys_shl_open (loader_data, filename) Line 1065  sys_shl_open (loader_data, filename)
1065  {  {
1066    static shl_t self = (shl_t) 0;    static shl_t self = (shl_t) 0;
1067    lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);    lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L);
1068      
1069    /* Since searching for a symbol against a NULL module handle will also    /* Since searching for a symbol against a NULL module handle will also
1070       look in everything else that was already loaded and exported with       look in everything else that was already loaded and exported with
1071       the -E compiler flag, we always cache a handle saved before any       the -E compiler flag, we always cache a handle saved before any
1072       modules are loaded.  */       modules are loaded.  */
1073    if (!self)    if (!self)
# Line 703  sys_shl_open (loader_data, filename) Line 1075  sys_shl_open (loader_data, filename)
1075        lt_ptr address;        lt_ptr address;
1076        shl_findsym (&self, "main", TYPE_UNDEFINED, &address);        shl_findsym (&self, "main", TYPE_UNDEFINED, &address);
1077      }      }
1078      
1079    if (!filename)    if (!filename)
1080      {      {
1081        module = self;        module = self;
# Line 714  sys_shl_open (loader_data, filename) Line 1086  sys_shl_open (loader_data, filename)
1086    
1087        if (!module)        if (!module)
1088          {          {
1089            MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));            LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1090          }          }
1091      }      }
1092      
1093    return module;    return module;
1094  }  }
1095    
# Line 730  sys_shl_close (loader_data, module) Line 1102  sys_shl_close (loader_data, module)
1102    
1103    if (module && (shl_unload ((shl_t) (module)) != 0))    if (module && (shl_unload ((shl_t) (module)) != 0))
1104      {      {
1105        MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1106        ++errors;        ++errors;
1107      }      }
1108    
# Line 748  sys_shl_sym (loader_data, module, symbol Line 1120  sys_shl_sym (loader_data, module, symbol
1120    /* sys_shl_open should never return a NULL module handle */    /* sys_shl_open should never return a NULL module handle */
1121    if (module == (lt_module) 0)    if (module == (lt_module) 0)
1122    {    {
1123      MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
1124    }    }
1125    else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))    else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))
1126      {      {
1127        if (!address)        if (!address)
1128          {          {
1129            MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));            LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1130          }          }
1131      }      }
1132      
1133    return address;    return address;
1134  }  }
1135    
# Line 808  sys_wll_open (loader_data, filename) Line 1180  sys_wll_open (loader_data, filename)
1180    if (ext)    if (ext)
1181      {      {
1182        /* FILENAME already has an extension. */        /* FILENAME already has an extension. */
1183        searchname = strdup (filename);        searchname = lt_estrdup (filename);
1184      }      }
1185    else    else
1186      {      {
1187        /* Append a `.' to stop Windows from adding an        /* Append a `.' to stop Windows from adding an
1188           implicit `.dll' extension. */           implicit `.dll' extension. */
1189        searchname = LT_DLMALLOC (char, 2+ strlen (filename));        searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename));
1190        if (!searchname)        if (searchname)
1191          {          sprintf (searchname, "%s.", filename);
           MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  
           return 0;  
         }  
       strcpy (searchname, filename);  
       strcat (searchname, ".");  
1192      }      }
1193      if (!searchname)
1194        return 0;
1195    
1196  #if __CYGWIN__  #if __CYGWIN__
1197    {    {
# Line 843  sys_wll_open (loader_data, filename) Line 1212  sys_wll_open (loader_data, filename)
1212       We check whether LoadLibrary is returning a handle to       We check whether LoadLibrary is returning a handle to
1213       an already loaded module, and simulate failure if we       an already loaded module, and simulate failure if we
1214       find one. */       find one. */
1215    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
1216    cur = handles;    cur = handles;
1217    while (cur)    while (cur)
1218      {      {
# Line 860  sys_wll_open (loader_data, filename) Line 1229  sys_wll_open (loader_data, filename)
1229    
1230        cur = cur->next;        cur = cur->next;
1231    }    }
1232    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
1233    
1234    if (cur || !module)    if (cur || !module)
1235      {      {
1236        MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1237        module = 0;        module = 0;
1238      }      }
1239    
# Line 880  sys_wll_close (loader_data, module) Line 1249  sys_wll_close (loader_data, module)
1249    
1250    if (FreeLibrary(module) == 0)    if (FreeLibrary(module) == 0)
1251      {      {
1252        MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1253        ++errors;        ++errors;
1254      }      }
1255    
# Line 897  sys_wll_sym (loader_data, module, symbol Line 1266  sys_wll_sym (loader_data, module, symbol
1266    
1267    if (!address)    if (!address)
1268      {      {
1269        MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1270      }      }
1271    
1272    return address;    return address;
# Line 942  sys_bedl_open (loader_data, filename) Line 1311  sys_bedl_open (loader_data, filename)
1311    
1312    if (image <= 0)    if (image <= 0)
1313      {      {
1314        MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1315        image = 0;        image = 0;
1316      }      }
1317    
# Line 958  sys_bedl_close (loader_data, module) Line 1327  sys_bedl_close (loader_data, module)
1327    
1328    if (unload_add_on ((image_id) module) != B_OK)    if (unload_add_on ((image_id) module) != B_OK)
1329      {      {
1330        MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1331        ++errors;        ++errors;
1332      }      }
1333    
# Line 976  sys_bedl_sym (loader_data, module, symbo Line 1345  sys_bedl_sym (loader_data, module, symbo
1345    
1346    if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)    if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
1347      {      {
1348        MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1349        address = 0;        address = 0;
1350      }      }
1351    
# Line 1010  sys_dld_open (loader_data, filename) Line 1379  sys_dld_open (loader_data, filename)
1379  {  {
1380    lt_module module = strdup (filename);    lt_module module = strdup (filename);
1381    
1382    if (!module)    if (dld_link (filename) != 0)
     {  
       MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  
       module = 0;  
     }  
   else if (dld_link (filename) != 0)  
1383      {      {
1384        MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
1385        LT_DLFREE (module);        LT_DLFREE (module);
1386        module = 0;        module = 0;
1387      }      }
# Line 1034  sys_dld_close (loader_data, module) Line 1398  sys_dld_close (loader_data, module)
1398    
1399    if (dld_unlink_by_file ((char*)(module), 1) != 0)    if (dld_unlink_by_file ((char*)(module), 1) != 0)
1400      {      {
1401        MUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE));
1402        ++errors;        ++errors;
1403      }      }
1404    else    else
# Line 1055  sys_dld_sym (loader_data, module, symbol Line 1419  sys_dld_sym (loader_data, module, symbol
1419    
1420    if (!address)    if (!address)
1421      {      {
1422        MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1423      }      }
1424    
1425    return address;    return address;
# Line 1090  presym_init (loader_data) Line 1454  presym_init (loader_data)
1454  {  {
1455    int errors = 0;    int errors = 0;
1456    
1457    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
1458    
1459    preloaded_symbols = 0;    preloaded_symbols = 0;
1460    if (default_preloaded_symbols)    if (default_preloaded_symbols)
# Line 1098  presym_init (loader_data) Line 1462  presym_init (loader_data)
1462        errors = lt_dlpreload (default_preloaded_symbols);        errors = lt_dlpreload (default_preloaded_symbols);
1463      }      }
1464    
1465    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
1466    
1467    return errors;    return errors;
1468  }  }
# Line 1108  presym_free_symlists () Line 1472  presym_free_symlists ()
1472  {  {
1473    lt_dlsymlists_t *lists;    lt_dlsymlists_t *lists;
1474    
1475    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
1476    
1477    lists = preloaded_symbols;    lists = preloaded_symbols;
1478    while (lists)    while (lists)
# Line 1120  presym_free_symlists () Line 1484  presym_free_symlists ()
1484      }      }
1485    preloaded_symbols = 0;    preloaded_symbols = 0;
1486    
1487    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
1488    
1489    return 0;    return 0;
1490  }  }
# Line 1141  presym_add_symlist (preloaded) Line 1505  presym_add_symlist (preloaded)
1505    lt_dlsymlists_t *lists;    lt_dlsymlists_t *lists;
1506    int              errors   = 0;    int              errors   = 0;
1507    
1508    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
1509    
1510    lists = preloaded_symbols;    lists = preloaded_symbols;
1511    while (lists)    while (lists)
# Line 1153  presym_add_symlist (preloaded) Line 1517  presym_add_symlist (preloaded)
1517        lists = lists->next;        lists = lists->next;
1518      }      }
1519    
1520    tmp = LT_DLMALLOC (lt_dlsymlists_t, 1);    tmp = LT_EMALLOC (lt_dlsymlists_t, 1);
1521    if (tmp)    if (tmp)
1522      {      {
1523        memset (tmp, 0, 1*sizeof(lt_dlsymlists_t));        memset (tmp, 0, sizeof(lt_dlsymlists_t));
1524        tmp->syms = preloaded;        tmp->syms = preloaded;
1525        tmp->next = preloaded_symbols;        tmp->next = preloaded_symbols;
1526        preloaded_symbols = tmp;        preloaded_symbols = tmp;
1527      }      }
1528    else    else
1529      {      {
       MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  
1530        ++errors;        ++errors;
1531      }      }
1532    
1533   done:   done:
1534    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
1535    return errors;    return errors;
1536  }  }
1537    
# Line 1180  presym_open (loader_data, filename) Line 1543  presym_open (loader_data, filename)
1543    lt_dlsymlists_t *lists;    lt_dlsymlists_t *lists;
1544    lt_module        module = (lt_module) 0;    lt_module        module = (lt_module) 0;
1545    
1546    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
1547    lists = preloaded_symbols;    lists = preloaded_symbols;
1548    
1549    if (!lists)    if (!lists)
1550      {      {
1551        MUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS));
1552        goto done;        goto done;
1553      }      }
1554    
1555      /* Can't use NULL as the reflective symbol header, as NULL is
1556         used to mark the end of the entire symbol list.  Self-dlpreopened
1557         symbols follow this magic number, chosen to be an unlikely
1558         clash with a real module name.  */
1559    if (!filename)    if (!filename)
1560      {      {
1561        filename = "@PROGRAM@";        filename = "@PROGRAM@";
# Line 1211  presym_open (loader_data, filename) Line 1578  presym_open (loader_data, filename)
1578        lists = lists->next;        lists = lists->next;
1579      }      }
1580    
1581    MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
1582    
1583   done:   done:
1584    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
1585    return module;    return module;
1586  }  }
1587    
# Line 1247  presym_sym (loader_data, module, symbol) Line 1614  presym_sym (loader_data, module, symbol)
1614      ++syms;      ++syms;
1615    }    }
1616    
1617    MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
1618    
1619    return 0;    return 0;
1620  }  }
# Line 1263  static struct lt_user_dlloader presym = Line 1630  static struct lt_user_dlloader presym =
1630  /* --- DYNAMIC MODULE LOADING --- */  /* --- DYNAMIC MODULE LOADING --- */
1631    
1632    
1633    /* The type of a function used at each iteration of  foreach_dirinpath().  */
1634    typedef int     foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1,
1635                                                     lt_ptr data2));
1636    
1637    static  int     foreach_dirinpath     LT_PARAMS((const char *search_path,
1638                                                     const char *base_name,
1639                                                     foreach_callback_func *func,
1640                                                     lt_ptr data1, lt_ptr data2));
1641    
1642    static  int     find_file_callback    LT_PARAMS((char *filename, lt_ptr data,
1643                                                     lt_ptr ignored));
1644    static  int     find_handle_callback  LT_PARAMS((char *filename, lt_ptr data,
1645                                                     lt_ptr ignored));
1646    static  int     foreachfile_callback  LT_PARAMS((char *filename, lt_ptr data1,
1647                                                     lt_ptr data2));
1648    
1649    
1650    static  int     canonicalize_path     LT_PARAMS((const char *path,
1651                                                     char **pcanonical));
1652    static  int     argzize_path          LT_PARAMS((const char *path,
1653                                                     char **pargz,
1654                                                     size_t *pargz_len));
1655    static  FILE   *find_file             LT_PARAMS((const char *search_path,
1656                                                     const char *base_name,
1657                                                     char **pdir));
1658    static  lt_dlhandle *find_handle      LT_PARAMS((const char *search_path,
1659                                                     const char *base_name,
1660                                                     lt_dlhandle *handle));
1661    static  int     find_module           LT_PARAMS((lt_dlhandle *handle,
1662                                                     const char *dir,
1663                                                     const char *libdir,
1664                                                     const char *dlname,
1665                                                     const char *old_name,
1666                                                     int installed));
1667    static  int     free_vars             LT_PARAMS((char *dlname, char *oldname,
1668                                                     char *libdir, char *deplibs));
1669    static  int     load_deplibs          LT_PARAMS((lt_dlhandle handle,
1670                                                     char *deplibs));
1671    static  int     trim                  LT_PARAMS((char **dest,
1672                                                     const char *str));
1673    static  int     try_dlopen            LT_PARAMS((lt_dlhandle *handle,
1674                                                     const char *filename));
1675    static  int     tryall_dlopen         LT_PARAMS((lt_dlhandle *handle,
1676                                                     const char *filename));
1677    static  int     unload_deplibs        LT_PARAMS((lt_dlhandle handle));
1678    static  int     lt_argz_insert        LT_PARAMS((char **pargz,
1679                                                     size_t *pargz_len,
1680                                                     char *before,
1681                                                     const char *entry));
1682    static  int     lt_argz_insertinorder LT_PARAMS((char **pargz,
1683                                                     size_t *pargz_len,
1684                                                     const char *entry));
1685    static  int     lt_dlpath_insertdir   LT_PARAMS((char **ppath,
1686                                                     char *before,
1687                                                     const char *dir));
1688    
1689  static  char           *user_search_path= 0;  static  char           *user_search_path= 0;
1690  static  lt_dlloader    *loaders         = 0;  static  lt_dlloader    *loaders         = 0;
1691  static  lt_dlhandle     handles         = 0;  static  lt_dlhandle     handles         = 0;
# Line 1274  lt_dlinit () Line 1697  lt_dlinit ()
1697  {  {
1698    int         errors   = 0;    int         errors   = 0;
1699    
1700    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
1701    
1702    /* Initialize only at first call. */    /* Initialize only at first call. */
1703    if (++initialized == 1)    if (++initialized == 1)
# Line 1301  lt_dlinit () Line 1724  lt_dlinit ()
1724    
1725        if (presym_init (presym.dlloader_data))        if (presym_init (presym.dlloader_data))
1726          {          {
1727            MUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));            LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER));
1728            ++errors;            ++errors;
1729          }          }
1730        else if (errors != 0)        else if (errors != 0)
1731          {          {
1732            MUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));            LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED));
1733            ++errors;            ++errors;
1734          }          }
1735      }      }
1736    
1737    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
1738    
1739    return errors;    return errors;
1740  }  }
# Line 1328  lt_dlpreload (preloaded) Line 1751  lt_dlpreload (preloaded)
1751      }      }
1752    else    else
1753      {      {
       const char *errormsg = 0;  
   
1754        presym_free_symlists();        presym_free_symlists();
1755      
1756        MUTEX_LOCK ();        LT_DLMUTEX_LOCK ();
1757        if (default_preloaded_symbols)        if (default_preloaded_symbols)
1758          {          {
1759            errors = lt_dlpreload (default_preloaded_symbols);            errors = lt_dlpreload (default_preloaded_symbols);
1760          }          }
1761        MUTEX_UNLOCK ();        LT_DLMUTEX_UNLOCK ();
1762      }      }
1763    
1764    return errors;    return errors;
# Line 1347  int Line 1768  int
1768  lt_dlpreload_default (preloaded)  lt_dlpreload_default (preloaded)
1769       const lt_dlsymlist *preloaded;       const lt_dlsymlist *preloaded;
1770  {  {
1771    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
1772    default_preloaded_symbols = preloaded;    default_preloaded_symbols = preloaded;
1773    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
1774    return 0;    return 0;
1775  }  }
1776    
# Line 1358  lt_dlexit () Line 1779  lt_dlexit ()
1779  {  {
1780    /* shut down libltdl */    /* shut down libltdl */
1781    lt_dlloader *loader;    lt_dlloader *loader;
   const char  *errormsg;  
1782    int          errors   = 0;    int          errors   = 0;
1783    
1784    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
1785    loader = loaders;    loader = loaders;
1786    
1787    if (!initialized)    if (!initialized)
1788      {      {
1789        MUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN));
1790        ++errors;        ++errors;
1791        goto done;        goto done;
1792      }      }
# Line 1422  lt_dlexit () Line 1842  lt_dlexit ()
1842      }      }
1843    
1844   done:   done:
1845    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
1846    return errors;    return errors;
1847  }  }
1848    
# Line 1436  tryall_dlopen (handle, filename) Line 1856  tryall_dlopen (handle, filename)
1856    const char    *saved_error;    const char    *saved_error;
1857    int            errors         = 0;    int            errors         = 0;
1858    
1859    MUTEX_GETERROR (saved_error);    LT_DLMUTEX_GETERROR (saved_error);
1860    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
1861    
1862    cur    = handles;    cur    = handles;
1863    loader = loaders;    loader = loaders;
# Line 1470  tryall_dlopen (handle, filename) Line 1890  tryall_dlopen (handle, filename)
1890    cur = *handle;    cur = *handle;
1891    if (filename)    if (filename)
1892      {      {
1893        cur->info.filename = strdup (filename);        cur->info.filename = lt_estrdup (filename);
1894        if (!cur->info.filename)        if (!cur->info.filename)
1895          {          {
           MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  
1896            ++errors;            ++errors;
1897            goto done;            goto done;
1898          }          }
# Line 1504  tryall_dlopen (handle, filename) Line 1923  tryall_dlopen (handle, filename)
1923      }      }
1924    
1925    cur->loader   = loader;    cur->loader   = loader;
1926    last_error    = saved_error;    LT_DLMUTEX_SETERROR (saved_error);
1927      
1928   done:   done:
1929    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
1930    
1931    return errors;    return errors;
1932  }  }
1933    
1934  static int  static int
1935    tryall_dlopen_module (handle, prefix, dirname, dlname)
1936         lt_dlhandle *handle;
1937         const char *prefix;
1938         const char *dirname;
1939         const char *dlname;
1940    {
1941      int      error        = 0;
1942      char     *filename    = 0;
1943      size_t   filename_len = 0;
1944      size_t   dirname_len  = LT_STRLEN (dirname);
1945    
1946      assert (handle);
1947      assert (dirname);
1948      assert (dlname);
1949    #ifdef LT_DIRSEP_CHAR
1950      /* Only canonicalized names (i.e. with DIRSEP chars already converted)
1951         should make it into this function:  */
1952      assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
1953    #endif
1954    
1955      if (dirname[dirname_len -1] == '/')
1956        --dirname_len;
1957      filename_len = dirname_len + 1 + LT_STRLEN (dlname);
1958    
1959      /* Allocate memory, and combine DIRNAME and MODULENAME into it.
1960         The PREFIX (if any) is handled below.  */
1961      filename  = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);
1962      if (!filename)
1963        return 1;
1964    
1965      sprintf (filename, "%.*s/%s", (int) dirname_len, dirname, dlname);
1966    
1967      /* Now that we have combined DIRNAME and MODULENAME, if there is
1968         also a PREFIX to contend with, simply recurse with the arguments
1969         shuffled.  Otherwise, attempt to open FILENAME as a module.  */
1970      if (prefix)
1971        {
1972          tryall_dlopen_module (handle, 0, prefix, filename);
1973        }
1974      else if (tryall_dlopen (handle, filename) != 0)
1975        {
1976          ++error;
1977        }
1978    
1979      LT_DLFREE (filename);
1980      return error;
1981    }
1982    
1983    static int
1984  find_module (handle, dir, libdir, dlname, old_name, installed)  find_module (handle, dir, libdir, dlname, old_name, installed)
1985       lt_dlhandle *handle;       lt_dlhandle *handle;
1986       const char *dir;       const char *dir;
# Line 1521  find_module (handle, dir, libdir, dlname Line 1989  find_module (handle, dir, libdir, dlname
1989       const char *old_name;       const char *old_name;
1990       int installed;       int installed;
1991  {  {
1992    int   error;    /* Try to open the old library first; if it was dlpreopened,
   char  *filename;  
   
   /* try to open the old library first; if it was dlpreopened,  
1993       we want the preopened version of it, even if a dlopenable       we want the preopened version of it, even if a dlopenable
1994       module is available */       module is available.  */
1995    if (old_name && tryall_dlopen(handle, old_name) == 0)    if (old_name && tryall_dlopen (handle, old_name) == 0)
1996      {      {
1997        return 0;        return 0;
1998      }      }
1999    
2000    /* try to open the dynamic library */    /* Try to open the dynamic library.  */
2001    if (dlname)    if (dlname)
2002      {      {
       size_t len;  
   
2003        /* try to open the installed module */        /* try to open the installed module */
2004        if (installed && libdir)        if (installed && libdir)
2005          {          {
2006            len       = strlen (libdir) + 1 + strlen (dlname);            if (tryall_dlopen_module (handle, 0, libdir, dlname) == 0)
2007            filename  = LT_DLMALLOC (char, 1+ len);              return 0;
   
           if (!filename)  
             {  
               MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  
               return 1;  
             }  
   
           sprintf (filename, "%s/%s", libdir, dlname);  
           error = (tryall_dlopen (handle, filename) != 0);  
           LT_DLFREE (filename);  
   
           if (!error)  
             {  
               return 0;  
             }  
2008          }          }
2009    
2010        /* try to open the not-installed module */        /* try to open the not-installed module */
2011        if (!installed)        if (!installed)
2012          {          {
2013            len = (dir ? strlen (dir) : 0) + strlen (objdir) + strlen (dlname);            if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
2014            filename = LT_DLMALLOC (char, 1+ len);              return 0;
   
           if (!filename)  
             {  
               MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  
               return 1;  
             }  
   
           if (dir)  
             {  
               strcpy (filename, dir);  
             }  
           else  
             {  
               *filename = 0;  
             }  
           strcat(filename, objdir);  
           strcat(filename, dlname);  
   
           error = tryall_dlopen (handle, filename) != 0;  
           LT_DLFREE (filename);  
           if (!error)  
             {  
               return 0;  
             }  
2015          }          }
2016    
2017        /* maybe it was moved to another directory */        /* maybe it was moved to another directory */
2018        {        {
2019          len      = (dir ? strlen (dir) : 0) + strlen (dlname);            if (tryall_dlopen_module (handle, 0, dir, dlname) == 0)
2020          filename = LT_DLMALLOC (char, 1+ len);              return 0;
2021          }
2022        }
2023    
2024      return 1;
2025    }
2026    
2027    
2028    static int
2029    canonicalize_path (path, pcanonical)
2030         const char *path;
2031         char **pcanonical;
2032    {
2033      char *canonical = 0;
2034    
2035      assert (path && *path);
2036      assert (pcanonical);
2037    
2038          if (dir)    canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));
2039      if (!canonical)
2040        return 1;
2041    
2042      {
2043        size_t dest = 0;
2044        size_t src;
2045        for (src = 0; path[src] != LT_EOS_CHAR; ++src)
2046          {
2047            /* Path separators are not copied to the beginning or end of
2048               the destination, or if another separator would follow
2049               immediately.  */
2050            if (path[src] == LT_PATHSEP_CHAR)
2051            {            {
2052              strcpy (filename, dir);              if ((dest == 0)
2053                    || (path[1+ src] == LT_PATHSEP_CHAR)
2054                    || (path[1+ src] == LT_EOS_CHAR))
2055                  continue;
2056            }            }
2057          else  
2058            /* Anything other than a directory separator is copied verbatim.  */
2059            if ((path[src] != '/')
2060    #ifdef LT_DIRSEP_CHAR
2061                && (path[src] != LT_DIRSEP_CHAR)
2062    #endif
2063                )
2064            {            {
2065              *filename = 0;              canonical[dest++] = path[src];
2066            }            }
2067          strcat(filename, dlname);          /* Directory separators are converted and copied only if they are
2068               not at the end of a path -- i.e. before a path separator or
2069          error = (tryall_dlopen (handle, filename) != 0);             NULL terminator.  */
2070          LT_DLFREE (filename);          else if ((path[1+ src] != LT_PATHSEP_CHAR)
2071          if (!error)                   && (path[1+ src] != LT_EOS_CHAR)
2072    #ifdef LT_DIRSEP_CHAR
2073                     && (path[1+ src] != LT_DIRSEP_CHAR)
2074    #endif
2075                     && (path[1+ src] != '/'))
2076            {            {
2077              return 0;              canonical[dest++] = '/';
2078            }            }
2079        }        }
     }  
2080    
2081    return 1;      /* Add an end-of-string marker at the end.  */
2082        canonical[dest] = LT_EOS_CHAR;
2083      }
2084    
2085      /* Assign new value.  */
2086      *pcanonical = canonical;
2087    
2088      return 0;
2089  }  }
2090    
2091  static char*  static int
2092  canonicalize_path (path)  argzize_path (path, pargz, pargz_len)
2093       const char *path;       const char *path;
2094         char **pargz;
2095         size_t *pargz_len;
2096  {  {
2097    char *canonical = 0;    error_t error;
2098    
2099    if (path && *path)    assert (path);
2100      {    assert (pargz);
2101        char *ptr = strdup (path);    assert (pargz_len);
       canonical = ptr;  
2102    
2103  #ifdef LT_DIRSEP_CHAR    if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
2104        /* Avoid this overhead where '/' is the only separator. */      {
2105        while (ptr = strchr (ptr, LT_DIRSEP_CHAR))        switch (error)
2106          {          {
2107            *ptr++ = '/';          case ENOMEM:
2108              LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2109              break;
2110            default:
2111              LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
2112              break;
2113          }          }
2114  #endif  
2115          return 1;
2116      }      }
2117    
2118    return canonical;    return 0;
2119  }  }
2120    
2121  static lt_ptr  /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
2122  find_file (basename, search_path, pdir, handle)     of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
2123       const char *basename;     non-zero or all elements are exhausted.  If BASE_NAME is non-NULL,
2124       it is appended to each SEARCH_PATH element before FUNC is called.  */
2125    static int
2126    foreach_dirinpath (search_path, base_name, func, data1, data2)
2127       const char *search_path;       const char *search_path;
2128       char **pdir;       const char *base_name;
2129       lt_dlhandle *handle;       foreach_callback_func *func;
2130  {       lt_ptr data1;
2131    /* When handle != NULL search a library, otherwise a file       lt_ptr data2;
2132       return NULL on failure, otherwise the file/handle.  */  {
2133      int   result          = 0;
2134    lt_ptr    result      = 0;    int   filenamesize    = 0;
2135    char     *filename    = 0;    int   lenbase         = LT_STRLEN (base_name);
2136    int       filenamesize= 0;    int   argz_len        = 0;
2137    int       lenbase     = strlen (basename);    char *argz            = 0;
2138    char     *canonical   = 0;    char *filename        = 0;
2139    char     *next        = 0;    char *canonical       = 0;
2140    
2141    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
2142    
2143    if (!search_path || !*search_path)    if (!search_path || !*search_path)
2144      {      {
2145        MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2146        goto cleanup;        goto cleanup;
2147      }      }
2148    
2149    canonical = canonicalize_path (search_path);    if (canonicalize_path (search_path, &canonical) != 0)
2150    if (!canonical)      goto cleanup;
     {  
       MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  
       goto cleanup;  
     }  
2151    
2152    next = canonical;    if (argzize_path (canonical, &argz, &argz_len) != 0)
2153    while (next)      goto cleanup;
     {  
       int lendir;  
       char *cur = next;  
2154    
2155        next = strchr (cur, LT_PATHSEP_CHAR);    {
2156        if (!next)      char *dir_name = 0;
2157          {      while ((dir_name = argz_next (argz, argz_len, dir_name)))
2158            next = cur + strlen (cur);        {
2159          }          int lendir = LT_STRLEN (dir_name);
2160    
2161        lendir = next - cur;          if (lendir +1 +lenbase >= filenamesize)
       if (*next == LT_PATHSEP_CHAR)  
2162          {          {
2163            ++next;            LT_DLFREE (filename);
2164          }            filenamesize  = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */
2165        else            filename      = LT_EMALLOC (char, filenamesize);
2166          {            if (!filename)
2167            next = 0;              goto cleanup;
2168          }          }
2169    
2170        if (lendir == 0)          strncpy (filename, dir_name, lendir);
2171          {          if (base_name && *base_name)
2172            continue;            {
2173          }              if (filename[lendir -1] != '/')
2174                  filename[lendir++] = '/';
2175                strcpy (filename +lendir, base_name);
2176              }
2177    
2178        if (lendir + 1 + lenbase >= filenamesize)          if ((result = (*func) (filename, data1, data2)))
2179          {            {
2180            LT_DLFREE (filename);              break;
2181            filenamesize = lendir + 1 + lenbase + 1;            }
2182            filename = LT_DLMALLOC (char, filenamesize);        }
2183      }
2184    
2185            if (!filename)   cleanup:
2186              {    LT_DLFREE (argz);
2187                MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));    LT_DLFREE (canonical);
2188                goto cleanup;    LT_DLFREE (filename);
             }  
         }  
2189    
2190        strncpy(filename, cur, lendir);    LT_DLMUTEX_UNLOCK ();
       if (filename[lendir-1] != '/')  
         {  
           filename[lendir++] = '/';  
         }  
       strcpy(filename+lendir, basename);  
       if (handle)  
         {  
           if (tryall_dlopen (handle, filename) == 0)  
             {  
               result = (lt_ptr) handle;  
               goto cleanup;  
             }  
         }  
       else  
         {  
           FILE *file = fopen (filename, LT_READTEXT_MODE);  
           if (file)  
             {  
               LT_DLFREE (*pdir);  
2191    
2192                filename[lendir] = '\0';    return result;
2193                *pdir = strdup(filename);  }
               if (!*pdir)  
                 {  
                   /* We could have even avoided the strdup,  
                      but there would be some memory overhead. */  
                   *pdir = filename;  
                   filename = 0;  
                 }  
2194    
2195                result = (lt_ptr) file;  /* If FILEPATH can be opened, store the name of the directory component
2196                goto cleanup;     in DATA1, and the opened FILE* structure address in DATA2.  Otherwise
2197              }     DATA1 is unchanged, but DATA2 is set to a pointer to NULL.  */
2198          }  static int
2199    find_file_callback (filename, data1, data2)
2200         char *filename;
2201         lt_ptr data1;
2202         lt_ptr data2;
2203    {
2204      char       **pdir     = (char **) data1;
2205      FILE       **pfile    = (FILE **) data2;
2206      int        is_done    = 0;
2207    
2208      assert (filename && *filename);
2209      assert (pdir);
2210      assert (pfile);
2211    
2212      if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
2213        {
2214          char *dirend = strrchr (filename, '/');
2215    
2216          if (dirend > filename)
2217            *dirend   = LT_EOS_CHAR;
2218    
2219          LT_DLFREE (*pdir);
2220          *pdir   = lt_estrdup (filename);
2221          is_done = (*pdir == 0) ? -1 : 1;
2222      }      }
2223    
2224    MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));    return is_done;
2225    }
2226    
2227   cleanup:  static FILE *
2228    LT_DLFREE (filename);  find_file (search_path, base_name, pdir)
2229    LT_DLFREE (canonical);       const char *search_path;
2230         const char *base_name;
2231         char **pdir;
2232    {
2233      FILE *file = 0;
2234    
2235    MUTEX_UNLOCK ();    foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
2236    
2237    return result;    return file;
2238  }  }
2239    
2240  static int  static int
2241  load_deplibs(handle, deplibs)  find_handle_callback (filename, data, ignored)
2242         char *filename;
2243         lt_ptr data;
2244         lt_ptr ignored;
2245    {
2246      lt_dlhandle  *handle  = (lt_dlhandle *) data;
2247      int           found   = access (filename, R_OK);
2248    
2249      /* Bail out if file cannot be read...  */
2250      if (!found)
2251        return 0;
2252    
2253      /* Try to dlopen the file, but do not continue searching in any
2254         case.  */
2255      if (tryall_dlopen (handle, filename) != 0)
2256        *handle = 0;
2257    
2258      return 1;
2259    }
2260    
2261    /* If HANDLE was found return it, otherwise return 0.  If HANDLE was
2262       found but could not be opened, *HANDLE will be set to 0.  */
2263    static lt_dlhandle *
2264    find_handle (search_path, base_name, handle)
2265         const char *search_path;
2266         const char *base_name;
2267         lt_dlhandle *handle;
2268    {
2269      if (!search_path)
2270        return 0;
2271    
2272      if (!foreach_dirinpath (search_path, base_name, find_handle_callback,
2273                              handle, 0))
2274        return 0;
2275    
2276      return handle;
2277    }
2278    
2279    static int
2280    load_deplibs (handle, deplibs)
2281       lt_dlhandle handle;       lt_dlhandle handle;
2282       char *deplibs;       char *deplibs;
2283  {  {
2284  #if LTDL_DLOPEN_DEPLIBS  #if LTDL_DLOPEN_DEPLIBS
2285    char  *p, *save_search_path;    char  *p, *save_search_path = 0;
2286    int   depcount = 0;    int   depcount = 0;
2287    int   i;    int   i;
2288    char  **names = 0;    char  **names = 0;
# Line 1782  load_deplibs(handle, deplibs) Line 2298  load_deplibs(handle, deplibs)
2298      }      }
2299    ++errors;    ++errors;
2300    
2301    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
2302    save_search_path = strdup (user_search_path);    if (user_search_path)
   if (user_search_path && !save_search_path)  
2303      {      {
2304        MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));        save_search_path = lt_estrdup (user_search_path);
2305        goto cleanup;        if (!save_search_path)
2306            goto cleanup;
2307      }      }
2308    
2309    /* extract search paths and count deplibs */    /* extract search paths and count deplibs */
# Line 1829  load_deplibs(handle, deplibs) Line 2345  load_deplibs(handle, deplibs)
2345    LT_DLFREE (user_search_path);    LT_DLFREE (user_search_path);
2346    user_search_path = save_search_path;    user_search_path = save_search_path;
2347    
2348    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
2349    
2350    if (!depcount)    if (!depcount)
2351      {      {
# Line 1837  load_deplibs(handle, deplibs) Line 2353  load_deplibs(handle, deplibs)
2353        goto cleanup;        goto cleanup;
2354      }      }
2355    
2356    names = LT_DLMALLOC (char *, depcount * sizeof (char*));    names = LT_EMALLOC (char *, depcount * sizeof (char*));
2357    if (!names)    if (!names)
2358      {      goto cleanup;
       goto cleanup;  
     }  
2359    
2360    /* now only extract the actual deplibs */    /* now only extract the actual deplibs */
2361    depcount = 0;    depcount = 0;
# Line 1867  load_deplibs(handle, deplibs) Line 2381  load_deplibs(handle, deplibs)
2381                *end = 0; /* set a temporary string terminator */                *end = 0; /* set a temporary string terminator */
2382                if (strncmp(p, "-l", 2) == 0)                if (strncmp(p, "-l", 2) == 0)
2383                  {                  {
2384                    name = LT_DLMALLOC (char, 3+ /* "lib" */ strlen (p+2) + 1);                    size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
2385                      name = LT_EMALLOC (char, 1+ name_len);
2386                    if (name)                    if (name)
2387                      {                      sprintf (name, "lib%s", p+2);
                       sprintf (name, "lib%s", p+2);  
                     }  
2388                  }                  }
2389                else                else
2390                  {                  name = lt_estrdup(p);
                   name = strdup(p);  
                 }  
2391    
2392                if (name)                if (!name)
2393                  {                  goto cleanup_names;
2394                    names[depcount++] = name;  
2395                  }                names[depcount++] = name;
               else  
                 {  
                   goto cleanup_names;  
                 }  
2396                *end = save;                *end = save;
2397              }              }
2398            p = end;            p = end;
# Line 1901  load_deplibs(handle, deplibs) Line 2408  load_deplibs(handle, deplibs)
2408      {      {
2409        int       j = 0;        int       j = 0;
2410    
2411        handle->deplibs = (lt_dlhandle*) LT_DLMALLOC (lt_dlhandle *, depcount);        handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount);
2412        if (!handle->deplibs)        if (!handle->deplibs)
2413              {          goto cleanup;
           goto cleanup;  
             }  
2414    
2415        for (i = 0; i < depcount; ++i)        for (i = 0; i < depcount; ++i)
2416          {          {
# Line 1934  load_deplibs(handle, deplibs) Line 2439  load_deplibs(handle, deplibs)
2439  }  }
2440    
2441  static int  static int
2442  unload_deplibs(handle)  unload_deplibs (handle)
2443       lt_dlhandle handle;       lt_dlhandle handle;
2444  {  {
2445    int i;    int i;
# Line 1962  trim (dest, str) Line 2467  trim (dest, str)
2467    /* remove the leading and trailing "'" from str    /* remove the leading and trailing "'" from str
2468       and store the result in dest */       and store the result in dest */
2469    const char *end   = strrchr (str, '\'');    const char *end   = strrchr (str, '\'');
2470    int   len         = strlen  (str);    int   len         = LT_STRLEN (str);
2471    char *tmp;    char *tmp;
2472    
2473    LT_DLFREE (*dest);    LT_DLFREE (*dest);
2474    
2475    if (len > 3 && str[0] == '\'')    if (len > 3 && str[0] == '\'')
2476      {      {
2477        tmp = LT_DLMALLOC (char, end - str);        tmp = LT_EMALLOC (char, end - str);
2478        if (!tmp)        if (!tmp)
2479          {          return 1;
           last_error = LT_DLSTRERROR (NO_MEMORY);  
           return 1;  
         }  
2480    
2481        strncpy(tmp, &str[1], (end - str) - 1);        strncpy(tmp, &str[1], (end - str) - 1);
2482        tmp[len-3] = '\0';        tmp[len-3] = LT_EOS_CHAR;
2483        *dest = tmp;        *dest = tmp;
2484      }      }
2485    else    else
# Line 1989  trim (dest, str) Line 2491  trim (dest, str)
2491  }  }
2492    
2493  static int  static int
2494  free_vars( dlname, oldname, libdir, deplibs)  free_vars (dlname, oldname, libdir, deplibs)
2495       char *dlname;       char *dlname;
2496       char *oldname;       char *oldname;
2497       char *libdir;       char *libdir;
# Line 2003  free_vars( dlname, oldname, libdir, depl Line 2505  free_vars( dlname, oldname, libdir, depl
2505    return 0;    return 0;
2506  }  }
2507    
2508  lt_dlhandle  int
2509  lt_dlopen (filename)  try_dlopen (phandle, filename)
2510         lt_dlhandle *phandle;
2511       const char *filename;       const char *filename;
2512  {  {
2513    lt_dlhandle handle = 0, newhandle;    const char *  ext             = 0;
2514    const char *ext;    const char *  saved_error     = 0;
2515    const char *saved_error;    char *        canonical       = 0;
2516    char  *canonical = 0, *basename = 0, *dir = 0, *name = 0;    char *        base_name       = 0;
2517      char *        dir             = 0;
2518      char *        name            = 0;
2519      int           errors          = 0;
2520      lt_dlhandle   newhandle;
2521    
2522      assert (phandle);
2523      assert (*phandle == 0);
2524    
2525    MUTEX_GETERROR (saved_error);    LT_DLMUTEX_GETERROR (saved_error);
2526    
2527    /* dlopen self? */    /* dlopen self? */
2528    if (!filename)    if (!filename)
2529      {      {
2530        handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);        *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
2531        if (!handle)        if (*phandle == 0)
2532          {          return 1;
           MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  
           return 0;  
         }  
2533    
2534        memset (handle, 0, 1*sizeof(struct lt_dlhandle_struct));        memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
2535        newhandle                 = handle;        newhandle = *phandle;
2536    
2537        /* lt_dlclose()ing yourself is very bad!  Disallow it.  */        /* lt_dlclose()ing yourself is very bad!  Disallow it.  */
2538        LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);        LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG);
2539    
2540        if (tryall_dlopen (&newhandle, 0) != 0)        if (tryall_dlopen (&newhandle, 0) != 0)
2541          {          {
2542            LT_DLFREE (handle);            LT_DLFREE (*phandle);
2543            return 0;            return 1;
2544          }          }
2545    
2546        goto register_handle;        goto register_handle;
2547      }      }
2548    
2549    canonical = canonicalize_path (filename);    assert (filename && *filename);
2550    if (!canonical)  
2551      /* Doing this immediately allows internal functions to safely
2552         assume only canonicalized paths are passed.  */
2553      if (canonicalize_path (filename, &canonical) != 0)
2554      {      {
2555        MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));        ++errors;
2556        LT_DLFREE (handle);        goto cleanup;
       return 0;  
2557      }      }
2558    
2559    /* If the canonical module name is a path (relative or absolute)    /* If the canonical module name is a path (relative or absolute)
2560       then split it into a directory part and a name part.  */       then split it into a directory part and a name part.  */
2561    basename = strrchr (canonical, '/');    base_name = strrchr (canonical, '/');
2562    if (basename)    if (base_name)
2563      {      {
2564        ++basename;        size_t dirlen = (1+ base_name) - canonical;
2565        dir = LT_DLMALLOC (char, basename - canonical + 1);  
2566          dir = LT_EMALLOC (char, 1+ dirlen);
2567        if (!dir)        if (!dir)
2568          {          {
2569            MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));            ++errors;
           handle = 0;  
2570            goto cleanup;            goto cleanup;
2571          }          }
2572    
2573        strncpy (dir, canonical, basename - canonical);        strncpy (dir, canonical, dirlen);
2574        dir[basename - canonical] = '\0';        dir[dirlen] = LT_EOS_CHAR;
2575    
2576          ++base_name;
2577      }      }
2578    else    else
2579      {      LT_DLMEM_REASSIGN (base_name, canonical);
2580        basename = canonical;  
2581      }    assert (base_name && *base_name);
2582    
2583    /* Check whether we are opening a libtool module (.la extension).  */    /* Check whether we are opening a libtool module (.la extension).  */
2584    ext = strrchr(basename, '.');    ext = strrchr (base_name, '.');
2585    if (ext && strcmp(ext, ".la") == 0)    if (ext && strcmp (ext, archive_ext) == 0)
2586      {      {
2587        /* this seems to be a libtool module */        /* this seems to be a libtool module */
2588        FILE     *file = 0;        FILE *    file     = 0;
2589        int       i;        char *    dlname   = 0;
2590        char     *dlname = 0, *old_name = 0;        char *    old_name = 0;
2591        char     *libdir = 0, *deplibs = 0;        char *    libdir   = 0;
2592        char     *line;        char *    deplibs  = 0;
2593          char *    line     = 0;
2594        size_t    line_len;        size_t    line_len;
2595        int       error = 0;        int       i;
2596    
2597        /* if we can't find the installed flag, it is probably an        /* if we can't find the installed flag, it is probably an
2598           installed libtool archive, produced with an old version           installed libtool archive, produced with an old version
# Line 2087  lt_dlopen (filename) Line 2600  lt_dlopen (filename)
2600        int       installed = 1;        int       installed = 1;
2601    
2602        /* extract the module name from the file name */        /* extract the module name from the file name */
2603        name = LT_DLMALLOC (char, ext - basename + 1);        name = LT_EMALLOC (char, ext - base_name + 1);
2604        if (!name)        if (!name)
2605          {          {
2606            MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));            ++errors;
           handle = 0;  
2607            goto cleanup;            goto cleanup;
2608          }          }
2609    
2610        /* canonicalize the module name */        /* canonicalize the module name */
2611        for (i = 0; i < ext - basename; ++i)        for (i = 0; i < ext - base_name; ++i)
2612          {          {
2613            if (isalnum ((int)(basename[i])))            if (isalnum ((int)(base_name[i])))
2614              {              {
2615                name[i] = basename[i];                name[i] = base_name[i];
2616              }              }
2617            else            else
2618              {              {
2619                name[i] = '_';                name[i] = '_';
2620              }              }
2621          }          }
2622          name[ext - base_name] = LT_EOS_CHAR;
       name[ext - basename] = '\0';  
2623    
2624      /* Now try to open the .la file.  If there is no directory name      /* Now try to open the .la file.  If there is no directory name
2625         component, try to find it first in user_search_path and then other         component, try to find it first in user_search_path and then other
# Line 2116  lt_dlopen (filename) Line 2627  lt_dlopen (filename)
2627         yet found) try opening just the module name as passed.  */         yet found) try opening just the module name as passed.  */
2628        if (!dir)        if (!dir)
2629          {          {
2630            file = (FILE*) find_file(basename, user_search_path, &dir, 0);            const char *search_path;
2631    
2632              LT_DLMUTEX_LOCK ();
2633              search_path = user_search_path;
2634              if (search_path)
2635                file = find_file (user_search_path, base_name, &dir);
2636              LT_DLMUTEX_UNLOCK ();
2637    
2638            if (!file)            if (!file)
2639              {              {
2640                file = (FILE*) find_file(basename, getenv("LTDL_LIBRARY_PATH"),                search_path = getenv (LTDL_SEARCHPATH_VAR);
2641                                         &dir, 0);                if (search_path)
2642                    file = find_file (search_path, base_name, &dir);
2643              }              }
2644    
2645  #ifdef LTDL_SHLIBPATH_VAR  #ifdef LTDL_SHLIBPATH_VAR
2646            if (!file)            if (!file)
2647              {              {
2648                file = (FILE*) find_file(basename, getenv(LTDL_SHLIBPATH_VAR),                search_path = getenv (LTDL_SHLIBPATH_VAR);
2649                                         &dir, 0);                if (search_path)
2650                    file = find_file (search_path, base_name, &dir);
2651              }              }
2652  #endif  #endif
2653  #ifdef LTDL_SYSSEARCHPATH  #ifdef LTDL_SYSSEARCHPATH
2654            if (!file)            if (!file && sys_search_path)
2655              {              {
2656                file = (FILE*) find_file(basename, sys_search_path, &dir, 0);                file = find_file (sys_search_path, base_name, &dir);
2657              }              }
2658  #endif  #endif
2659          }          }
# Line 2141  lt_dlopen (filename) Line 2661  lt_dlopen (filename)
2661          {          {
2662            file = fopen (filename, LT_READTEXT_MODE);            file = fopen (filename, LT_READTEXT_MODE);
2663          }          }
       if (!file)  
         {  
           MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));  
         }  
2664    
2665          /* If we didn't find the file by now, it really isn't there.  Set
2666             the status flag, and bail out.  */
2667        if (!file)        if (!file)
2668          {          {
2669            handle = 0;            LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2670              ++errors;
2671            goto cleanup;            goto cleanup;
2672          }          }
2673    
2674        line_len = LT_FILENAME_MAX;        line_len = LT_FILENAME_MAX;
2675        line = LT_DLMALLOC (char, line_len);        line = LT_EMALLOC (char, line_len);
2676        if (!line)        if (!line)
2677          {          {
2678            fclose (file);            fclose (file);
2679            MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));            ++errors;
           handle = 0;  
2680            goto cleanup;            goto cleanup;
2681          }          }
2682    
2683        /* read the .la file */        /* read the .la file */
2684        while (!feof(file))        while (!feof (file))
2685          {          {
2686            if (!fgets (line, line_len, file))            if (!fgets (line, line_len, file))
2687              {              {
2688                break;                break;
2689              }              }
2690    
2691              /* Handle the case where we occasionally need to read a line
           /* Handle the case where we occasionally need to read a line  
2692               that is longer than the initial buffer size.  */               that is longer than the initial buffer size.  */
2693            while (line[strlen(line) -1] != '\n')            while (line[LT_STRLEN(line) -1] != '\n')
2694              {              {
2695                line = LT_DLREALLOC (char, line, line_len *2);                line = LT_DLREALLOC (char, line, line_len *2);
2696                if (!fgets (&line[line_len -1], line_len +1, file))                if (!fgets (&line[line_len -1], line_len +1, file))
# Line 2192  lt_dlopen (filename) Line 2709  lt_dlopen (filename)
2709  #define STR_DLNAME      "dlname="  #define STR_DLNAME      "dlname="
2710            if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)            if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0)
2711              {              {
2712                error = trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);                errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]);
2713              }              }
2714    
2715  #undef  STR_OLD_LIBRARY  #undef  STR_OLD_LIBRARY
# Line 2200  lt_dlopen (filename) Line 2717  lt_dlopen (filename)
2717            else if (strncmp (line, STR_OLD_LIBRARY,            else if (strncmp (line, STR_OLD_LIBRARY,
2718                              sizeof (STR_OLD_LIBRARY) - 1) == 0)                              sizeof (STR_OLD_LIBRARY) - 1) == 0)
2719              {              {
2720                error = trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);                errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]);
2721              }              }
2722  #undef  STR_LIBDIR  #undef  STR_LIBDIR
2723  #define STR_LIBDIR      "libdir="  #define STR_LIBDIR      "libdir="
2724            else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)            else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0)
2725              {              {
2726                error = trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);                errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]);
2727              }              }
2728    
2729  #undef  STR_DL_DEPLIBS  #undef  STR_DL_DEPLIBS
# Line 2214  lt_dlopen (filename) Line 2731  lt_dlopen (filename)
2731            else if (strncmp (line, STR_DL_DEPLIBS,            else if (strncmp (line, STR_DL_DEPLIBS,
2732                              sizeof (STR_DL_DEPLIBS) - 1) == 0)                              sizeof (STR_DL_DEPLIBS) - 1) == 0)
2733              {              {
2734                error = trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);                errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]);
2735              }              }
2736            else if (strcmp (line, "installed=yes\n") == 0)            else if (strcmp (line, "installed=yes\n") == 0)
2737              {              {
# Line 2231  lt_dlopen (filename) Line 2748  lt_dlopen (filename)
2748                                          sizeof (STR_LIBRARY_NAMES) - 1) == 0)                                          sizeof (STR_LIBRARY_NAMES) - 1) == 0)
2749              {              {
2750                char *last_libname;                char *last_libname;
2751                error = trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);                errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
2752                if (! error && dlname &&                if (!errors
2753                    (last_libname = strrchr (dlname, ' ')) != NULL)                    && dlname
2754                      && (last_libname = strrchr (dlname, ' ')) != 0)
2755                  {                  {
2756                    last_libname = strdup (last_libname + 1);                    last_libname = lt_estrdup (last_libname + 1);
2757                      if (!last_libname)
2758                        {
2759                          ++errors;
2760                          goto cleanup;
2761                        }
2762                    LT_DLMEM_REASSIGN (dlname, last_libname);                    LT_DLMEM_REASSIGN (dlname, last_libname);
2763                  }                  }
2764              }              }
2765    
2766            if (error)            if (errors)
2767              {              break;
               break;  
             }  
2768          }          }
2769    
2770        fclose (file);        fclose (file);
2771        LT_DLFREE (line);        LT_DLFREE (line);
2772    
2773        /* allocate the handle */        /* allocate the handle */
2774        handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);        *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
2775        if (!handle || error)        if (*phandle == 0)
2776          {          ++errors;
           LT_DLFREE (handle);  
           if (!error)  
             {  
               MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  
             }  
2777    
2778          if (errors)
2779            {
2780            free_vars (dlname, old_name, libdir, deplibs);            free_vars (dlname, old_name, libdir, deplibs);
2781            /* handle is already set to 0 */            LT_DLFREE (*phandle);
2782            goto cleanup;            goto cleanup;
2783          }          }
2784    
2785        memset (handle, 0, 1*sizeof(struct lt_dlhandle_struct));        assert (*phandle);
2786        if (load_deplibs (handle, deplibs) == 0)  
2787          memset (*phandle, 0, sizeof(struct lt_dlhandle_struct));
2788          if (load_deplibs (*phandle, deplibs) == 0)
2789          {          {
2790            newhandle = handle;            newhandle = *phandle;
2791            /* find_module may replace newhandle */            /* find_module may replace newhandle */
2792            if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))            if (find_module (&newhandle, dir, libdir, dlname, old_name, installed))
2793              {              {
2794                unload_deplibs (handle);                unload_deplibs (*phandle);
2795                error = 1;                ++errors;
2796              }              }
2797          }          }
2798        else        else
2799          {          {
2800            error = 1;            ++errors;
2801          }          }
2802    
2803        free_vars (dlname, old_name, libdir, deplibs);        free_vars (dlname, old_name, libdir, deplibs);
2804        if (error)        if (errors)
2805          {          {
2806            LT_DLFREE (handle);            LT_DLFREE (*phandle);
2807            goto cleanup;            goto cleanup;
2808          }          }
2809    
2810        if (handle != newhandle)        if (*phandle != newhandle)
2811          {          {
2812            unload_deplibs (handle);            unload_deplibs (*phandle);
2813          }          }
2814      }      }
2815    else    else
2816      {      {
2817        /* not a libtool module */        /* not a libtool module */
2818        handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);        *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
2819        if (!handle)        if (*phandle == 0)
2820          {          {
2821            MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));            ++errors;
           /* handle is already set to 0 */  
2822            goto cleanup;            goto cleanup;
2823          }          }
2824        handle->info.ref_count = 0;  
2825        /* non-libtool modules don't have dependencies */        memset (*phandle, 0, sizeof (struct lt_dlhandle_struct));
2826        handle->depcount    = 0;        newhandle = *phandle;
       handle->deplibs     = 0;  
       newhandle           = handle;  
2827    
2828        /* If the module has no directory name component, try to find it        /* If the module has no directory name component, try to find it
2829           first in user_search_path and then other prescribed paths.           first in user_search_path and then other prescribed paths.
2830           Otherwise (or in any case if the module was not yet found) try           Otherwise (or in any case if the module was not yet found) try
2831           opening just the module name as passed.  */           opening just the module name as passed.  */
2832        if ((dir || (!find_file (basename, user_search_path, 0, &newhandle)        if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
2833                     && !find_file (basename, getenv ("LTDL_LIBRARY_PATH"),                     && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name,
2834                                    0, &newhandle)                                      &newhandle)
2835  #ifdef LTDL_SHLIBPATH_VAR  #ifdef LTDL_SHLIBPATH_VAR
2836                     && !find_file (basename, getenv (LTDL_SHLIBPATH_VAR),                     && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
2837                                    0, &newhandle)                                      &newhandle)
2838  #endif  #endif
2839  #ifdef LTDL_SYSSEARCHPATH  #ifdef LTDL_SYSSEARCHPATH
2840                     && !find_file (basename, sys_search_path, 0, &newhandle)                     && !find_handle (sys_search_path, base_name, &newhandle)
2841  #endif  #endif
2842                     )) && tryall_dlopen (&newhandle, filename))                     )))
2843          {          {
2844            LT_DLFREE (handle);            tryall_dlopen (&newhandle, filename);
2845            }
2846    
2847          if (!newhandle)
2848            {
2849              LT_DLFREE (*phandle);
2850              ++errors;
2851            goto cleanup;            goto cleanup;
2852          }          }
2853      }      }
2854    
2855   register_handle:   register_handle:
2856    LT_DLMEM_REASSIGN (handle, newhandle);    LT_DLMEM_REASSIGN (*phandle, newhandle);
2857    
2858    if (handle->info.ref_count == 0)    if ((*phandle)->info.ref_count == 0)
2859      {      {
2860        handle->info.ref_count    = 1;        (*phandle)->info.ref_count        = 1;
2861        handle->info.name         = name;        LT_DLMEM_REASSIGN ((*phandle)->info.name, name);
       handle->next              = handles;  
2862    
2863        MUTEX_LOCK ();        LT_DLMUTEX_LOCK ();
2864        handles                   = handle;        (*phandle)->next          = handles;
2865        MUTEX_UNLOCK ();        handles                   = *phandle;
2866          LT_DLMUTEX_UNLOCK ();
       name = 0; /* don't free this during `cleanup' */  
2867      }      }
2868    
2869    MUTEX_SETERROR (saved_error);    LT_DLMUTEX_SETERROR (saved_error);
2870    
2871   cleanup:   cleanup:
2872    LT_DLFREE (dir);    LT_DLFREE (dir);
2873    LT_DLFREE (name);    LT_DLFREE (name);
2874    LT_DLFREE (canonical);    LT_DLFREE (canonical);
2875    
2876      return errors;
2877    }
2878    
2879    lt_dlhandle
2880    lt_dlopen (filename)
2881         const char *filename;
2882    {
2883      lt_dlhandle handle = 0;
2884    
2885      /* Just incase we missed a code path in try_dlopen() that reports
2886         an error, but forgets to reset handle... */
2887      if (try_dlopen (&handle, filename) != 0)
2888        return 0;
2889    
2890    return handle;    return handle;
2891  }  }
2892    
2893    /* If the last error messge store was `FILE_NOT_FOUND', then return
2894       non-zero.  */
2895    int
2896    file_not_found ()
2897    {
2898      const char *error = 0;
2899    
2900      LT_DLMUTEX_GETERROR (error);
2901      if (error == LT_DLSTRERROR (FILE_NOT_FOUND))
2902        return 1;
2903    
2904      return 0;
2905    }
2906    
2907    /* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to
2908       open the FILENAME as passed.  Otherwise try appending ARCHIVE_EXT,
2909       and if a file is still not found try again with SHLIB_EXT appended
2910       instead.  */
2911  lt_dlhandle  lt_dlhandle
2912  lt_dlopenext (filename)  lt_dlopenext (filename)
2913       const char *filename;       const char *filename;
2914  {  {
2915    lt_dlhandle handle;    lt_dlhandle   handle          = 0;
2916    char  *tmp;    char *        tmp             = 0;
2917    int   len;    char *        ext             = 0;
2918    const char *saved_error;    int           len;
2919      int           errors          = 0;
2920    MUTEX_GETERROR (saved_error);    int           file_found      = 1; /* until proven otherwise */
2921    
2922    if (!filename)    if (!filename)
2923      {      {
2924        return lt_dlopen (filename);        return lt_dlopen (filename);
2925      }      }
2926    
2927    len = strlen (filename);    assert (filename);
2928    if (!len)  
2929      len = LT_STRLEN (filename);
2930      ext = strrchr (filename, '.');
2931    
2932      /* If FILENAME already bears a suitable extension, there is no need
2933         to try appending additional extensions.  */
2934      if (ext && ((strcmp (ext, archive_ext) == 0)
2935    #ifdef LTDL_SHLIB_EXT
2936                  || (strcmp (ext, shlib_ext) == 0)
2937    #endif
2938          ))
2939      {      {
2940        MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));        return lt_dlopen (filename);
       return 0;  
2941      }      }
2942    
2943    /* try "filename.la" */    /* First try appending ARCHIVE_EXT.  */
2944    tmp = LT_DLMALLOC (char, len+4);    tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1);
2945    if (!tmp)    if (!tmp)
2946      {      return 0;
2947        MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  
       return 0;  
     }  
2948    strcpy (tmp, filename);    strcpy (tmp, filename);
2949    strcat (tmp, ".la");    strcat (tmp, archive_ext);
2950    handle = lt_dlopen (tmp);    errors = try_dlopen (&handle, tmp);
2951    if (handle)  
2952      /* If we found FILENAME, stop searching -- whether we were able to
2953         load the file as a module or not.  If the file exists but loading
2954         failed, it is better to return an error message here than to
2955         report FILE_NOT_FOUND when the alternatives (foo.so etc) are not
2956         in the module search path.  */
2957      if (handle || ((errors > 0) && file_not_found ()))
2958      {      {
       MUTEX_SETERROR (saved_error);  
2959        LT_DLFREE (tmp);        LT_DLFREE (tmp);
2960        return handle;        return handle;
2961      }      }
2962    
2963  #ifdef LTDL_SHLIB_EXT  #ifdef LTDL_SHLIB_EXT
2964    /* try "filename.EXT" */    /* Try appending SHLIB_EXT.   */
2965    if (strlen(shlib_ext) > 3)    if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext))
2966      {      {
2967        LT_DLFREE (tmp);        LT_DLFREE (tmp);
2968        tmp = LT_DLMALLOC (char, len + strlen (shlib_ext) + 1);        tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
2969        if (!tmp)        if (!tmp)
2970          {          return 0;
2971            MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  
           return 0;  
         }  
2972        strcpy (tmp, filename);        strcpy (tmp, filename);
2973      }      }
2974    else    else
2975      {      {
2976        tmp[len] = '\0';        tmp[len] = LT_EOS_CHAR;
2977      }      }
2978    
2979    strcat(tmp, shlib_ext);    strcat(tmp, shlib_ext);
2980    handle = lt_dlopen (tmp);    errors = try_dlopen (&handle, tmp);
2981    if (handle)  
2982      /* As before, if the file was found but loading failed, return now
2983         with the current error message.  */
2984      if (handle || ((errors > 0) && file_not_found ()))
2985      {      {
       MUTEX_SETERROR (saved_error);  
2986        LT_DLFREE (tmp);        LT_DLFREE (tmp);
2987        return handle;        return handle;
2988      }      }
2989  #endif  #endif
2990    
2991    /* try the normal file name */    /* Still here?  Then we really did fail to locate any of the file
2992    handle = lt_dlopen (filename);       names we tried.  */
2993    if (handle)    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
2994      LT_DLFREE (tmp);
2995      return 0;
2996    }
2997    
2998    
2999    int
3000    lt_argz_insert (pargz, pargz_len, before, entry)
3001         char **pargz;
3002         size_t *pargz_len;
3003         char *before;
3004         const char *entry;
3005    {
3006      error_t error;
3007    
3008      if ((error = argz_insert (pargz, pargz_len, before, entry)))
3009      {      {
3010        return handle;        switch (error)
3011            {
3012            case ENOMEM:
3013              LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
3014              break;
3015            default:
3016              LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
3017              break;
3018            }
3019          return 1;
3020      }      }
3021    
   MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));  
   LT_DLFREE (tmp);  
3022    return 0;    return 0;
3023  }  }
3024    
3025  int  int
3026    lt_argz_insertinorder (pargz, pargz_len, entry)
3027         char **pargz;
3028         size_t *pargz_len;
3029         const char *entry;
3030    {
3031      char *before = 0;
3032    
3033      assert (pargz);
3034      assert (pargz_len);
3035      assert (entry && *entry);
3036    
3037      if (*pargz)
3038        while ((before = argz_next (*pargz, *pargz_len, before)))
3039          {
3040            int cmp = strcmp (entry, before);
3041    
3042            if (cmp < 0)  break;
3043            if (cmp == 0) return 0; /* No duplicates! */
3044          }
3045    
3046      return lt_argz_insert (pargz, pargz_len, before, entry);
3047    }
3048    
3049    int
3050    lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
3051         char **pargz;
3052         size_t *pargz_len;
3053         const char *dirnam;
3054         struct dirent *dp;
3055    {
3056      char   *buf       = 0;
3057      size_t buf_len    = 0;
3058      char   *end       = 0;
3059      size_t end_offset = 0;
3060      size_t dir_len    = 0;
3061      int    errors     = 0;
3062    
3063      assert (pargz);
3064      assert (pargz_len);
3065      assert (dp);
3066    
3067      dir_len = LT_STRLEN (dirnam);
3068      end     = dp->d_name + LT_D_NAMLEN(dp);
3069    
3070      /* Ignore version numbers.  */
3071      {
3072        char *p;
3073        for (p = end; p -1 > dp->d_name; --p)
3074          if (strchr (".0123456789", p[-1]) == 0)
3075            break;
3076    
3077        if (*p == '.')
3078          end = p;
3079      }
3080    
3081      /* Ignore filename extension.  */
3082      {
3083        char *p;
3084        for (p = end -1; p > dp->d_name; --p)
3085          if (*p == '.')
3086            {
3087              end = p;
3088              break;
3089            }
3090      }
3091    
3092      /* Prepend the directory name.  */
3093      end_offset    = end - dp->d_name;
3094      buf_len       = dir_len + 1+ end_offset;
3095      buf           = LT_EMALLOC (char, 1+ buf_len);
3096      if (!buf)
3097        return ++errors;
3098    
3099      assert (buf);
3100    
3101      strcpy  (buf, dirnam);
3102      strcat  (buf, "/");
3103      strncat (buf, dp->d_name, end_offset);
3104      buf[buf_len] = LT_EOS_CHAR;
3105    
3106      /* Try to insert (in order) into ARGZ/ARGZ_LEN.  */
3107      if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
3108        ++errors;
3109    
3110      LT_DLFREE (buf);
3111    
3112      return errors;
3113    }
3114    
3115    int
3116    list_files_by_dir (dirnam, pargz, pargz_len)
3117         const char *dirnam;
3118         char **pargz;
3119         size_t *pargz_len;
3120    {
3121      DIR   *dirp     = 0;
3122      int    errors   = 0;
3123    
3124      assert (dirnam && *dirnam);
3125      assert (pargz);
3126      assert (pargz_len);
3127      assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
3128    
3129      dirp = opendir (dirnam);
3130      if (dirp)
3131        {
3132          struct dirent *dp = 0;
3133    
3134          while ((dp = readdir (dirp)))
3135            if (dp->d_name[0] != '.')
3136              if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp))
3137                {
3138                  ++errors;
3139                  break;
3140                }
3141    
3142          closedir (dirp);
3143        }
3144      else
3145        ++errors;
3146    
3147      return errors;
3148    }
3149    
3150    
3151    /* If there are any files in DIRNAME, call the function passed in
3152       DATA1 (with the name of each file and DATA2 as arguments).  */
3153    static int
3154    foreachfile_callback (dirname, data1, data2)
3155         char *dirname;
3156         lt_ptr data1;
3157         lt_ptr data2;
3158    {
3159      int (*func) LT_PARAMS((const char *filename, lt_ptr data))
3160            = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
3161    
3162      int     is_done  = 0;
3163      char   *argz     = 0;
3164      size_t  argz_len = 0;
3165    
3166      if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
3167        goto cleanup;
3168      if (!argz)
3169        goto cleanup;
3170    
3171      {
3172        char *filename = 0;
3173        while ((filename = argz_next (argz, argz_len, filename)))
3174          if ((is_done = (*func) (filename, data2)))
3175            break;
3176      }
3177    
3178     cleanup:
3179      LT_DLFREE (argz);
3180    
3181      return is_done;
3182    }
3183    
3184    
3185    /* Call FUNC for each unique extensionless file in SEARCH_PATH, along
3186       with DATA.  The filenames passed to FUNC would be suitable for
3187       passing to lt_dlopenext.  The extensions are stripped so that
3188       individual modules do not generate several entries (e.g. libfoo.la,
3189       libfoo.so, libfoo.so.1, libfoo.so.1.0.0).  If SEARCH_PATH is NULL,
3190       then the same directories that lt_dlopen would search are examined.  */
3191    int
3192    lt_dlforeachfile (search_path, func, data)
3193         const char *search_path;
3194         int (*func) LT_PARAMS ((const char *filename, lt_ptr data));
3195         lt_ptr data;
3196    {
3197      int is_done = 0;
3198    
3199      if (search_path)
3200        {
3201          /* If a specific path was passed, search only the directories
3202             listed in it.  */
3203          is_done = foreach_dirinpath (search_path, 0,
3204                                       foreachfile_callback, func, data);
3205        }
3206      else
3207        {
3208          /* Otherwise search the default paths.  */
3209          is_done = foreach_dirinpath (user_search_path, 0,
3210                                       foreachfile_callback, func, data);
3211          if (!is_done)
3212            {
3213              is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
3214                                           foreachfile_callback, func, data);
3215            }
3216    
3217    #ifdef LTDL_SHLIBPATH_VAR
3218          if (!is_done)
3219            {
3220              is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0,
3221                                           foreachfile_callback, func, data);
3222            }
3223    #endif
3224    #ifdef LTDL_SYSSEARCHPATH
3225          if (!is_done)
3226            {
3227              is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0,
3228                                           foreachfile_callback, func, data);
3229            }
3230    #endif
3231        }
3232    
3233      return is_done;
3234    }
3235    
3236    int
3237  lt_dlclose (handle)  lt_dlclose (handle)
3238       lt_dlhandle handle;       lt_dlhandle handle;
3239  {  {
3240    lt_dlhandle cur, last;    lt_dlhandle cur, last;
3241    int errors = 0;    int errors = 0;
3242    
3243    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
3244    
3245    /* check whether the handle is valid */    /* check whether the handle is valid */
3246    last = cur = handles;    last = cur = handles;
# Line 2454  lt_dlclose (handle) Line 3252  lt_dlclose (handle)
3252    
3253    if (!cur)    if (!cur)
3254      {      {
3255        MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3256        ++errors;        ++errors;
3257        goto done;        goto done;
3258      }      }
# Line 2490  lt_dlclose (handle) Line 3288  lt_dlclose (handle)
3288    
3289    if (LT_DLIS_RESIDENT (handle))    if (LT_DLIS_RESIDENT (handle))
3290      {      {
3291        MUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE));
3292        ++errors;        ++errors;
3293      }      }
3294    
3295   done:   done:
3296    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
3297    
3298    return errors;    return errors;
3299  }  }
# Line 2513  lt_dlsym (handle, symbol) Line 3311  lt_dlsym (handle, symbol)
3311    
3312    if (!handle)    if (!handle)
3313      {      {
3314        MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3315        return 0;        return 0;
3316      }      }
3317    
3318    if (!symbol)    if (!symbol)
3319      {      {
3320        MUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND));
3321        return 0;        return 0;
3322      }      }
3323    
3324    lensym = strlen(symbol);    lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
3325    if (handle->loader->sym_prefix)                                          + LT_STRLEN (handle->info.name);
     {  
       lensym += strlen(handle->loader->sym_prefix);  
     }  
   
   if (handle->info.name)  
     {  
       lensym += strlen(handle->info.name);  
     }  
3326    
3327    if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)    if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
3328      {      {
# Line 2540  lt_dlsym (handle, symbol) Line 3330  lt_dlsym (handle, symbol)
3330      }      }
3331    else    else
3332      {      {
3333        sym = LT_DLMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);        sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
3334      }        if (!sym)
3335            {
3336    if (!sym)            LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
3337      {            return 0;
3338        MUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));          }
       return 0;  
3339      }      }
3340    
3341    data = handle->loader->dlloader_data;    data = handle->loader->dlloader_data;
# Line 2554  lt_dlsym (handle, symbol) Line 3343  lt_dlsym (handle, symbol)
3343      {      {
3344        const char *saved_error;        const char *saved_error;
3345    
3346        MUTEX_GETERROR (saved_error);        LT_DLMUTEX_GETERROR (saved_error);
3347    
3348        /* this is a libtool module */        /* this is a libtool module */
3349        if (handle->loader->sym_prefix)        if (handle->loader->sym_prefix)
# Line 2580  lt_dlsym (handle, symbol) Line 3369  lt_dlsym (handle, symbol)
3369              }              }
3370            return address;            return address;
3371          }          }
3372        MUTEX_SETERROR (saved_error);        LT_DLMUTEX_SETERROR (saved_error);
3373      }      }
3374    
3375    /* otherwise try "symbol" */    /* otherwise try "symbol" */
# Line 2608  lt_dlerror () Line 3397  lt_dlerror ()
3397  {  {
3398    const char *error;    const char *error;
3399    
3400    MUTEX_GETERROR (error);    LT_DLMUTEX_GETERROR (error);
3401    MUTEX_SETERROR (0);    LT_DLMUTEX_SETERROR (0);
3402    
3403    return error;    return error ? error : LT_DLSTRERROR (UNKNOWN);
3404    }
3405    
3406    int
3407    lt_dlpath_insertdir (ppath, before, dir)
3408         char **ppath;
3409         char *before;
3410         const char *dir;
3411    {
3412      int    errors         = 0;
3413      char  *canonical      = 0;
3414      char  *argz           = 0;
3415      size_t argz_len       = 0;
3416    
3417      assert (ppath);
3418      assert (dir && *dir);
3419    
3420      if (canonicalize_path (dir, &canonical) != 0)
3421        {
3422          ++errors;
3423          goto cleanup;
3424        }
3425    
3426      assert (canonical && *canonical);
3427    
3428      /* If *PPATH is empty, set it to DIR.  */
3429      if (*ppath == 0)
3430        {
3431          assert (!before);         /* BEFORE cannot be set without PPATH.  */
3432          assert (dir);             /* Without DIR, don't call this function!  */
3433    
3434          *ppath = lt_estrdup (dir);
3435          if (*ppath == 0)
3436            ++errors;
3437    
3438          return errors;
3439        }
3440    
3441      assert (ppath && *ppath);
3442    
3443      if (argzize_path (*ppath, &argz, &argz_len) != 0)
3444        {
3445          ++errors;
3446          goto cleanup;
3447        }
3448    
3449      /* Convert BEFORE into an equivalent offset into ARGZ.  This only works
3450         if *PPATH is already canonicalized, and hence does not change length
3451         with respect to ARGZ.  We canonicalize each entry as it is added to
3452         the search path, and don't call this function with (uncanonicalized)
3453         user paths, so this is a fair assumption.  */
3454      if (before)
3455        {
3456          assert (*ppath <= before);
3457          assert (before - *ppath <= strlen (*ppath));
3458    
3459          before = before - *ppath + argz;
3460        }
3461    
3462      if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
3463        {
3464          ++errors;
3465          goto cleanup;
3466        }
3467    
3468      argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
3469      LT_DLMEM_REASSIGN (*ppath,  argz);
3470    
3471     cleanup:
3472      LT_DLFREE (canonical);
3473      LT_DLFREE (argz);
3474    
3475      return errors;
3476  }  }
3477    
3478  int  int
# Line 2620  lt_dladdsearchdir (search_dir) Line 3481  lt_dladdsearchdir (search_dir)
3481  {  {
3482    int errors = 0;    int errors = 0;
3483    
3484    if (!search_dir || !strlen(search_dir))    if (search_dir && *search_dir)
3485      {      {
3486        return errors;        LT_DLMUTEX_LOCK ();
3487          if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
3488            ++errors;
3489          LT_DLMUTEX_UNLOCK ();
3490      }      }
3491    
3492    MUTEX_LOCK ();    return errors;
3493    if (!user_search_path)  }
3494    
3495    int
3496    lt_dlinsertsearchdir (before, search_dir)
3497         const char *before;
3498         const char *search_dir;
3499    {
3500      int errors = 0;
3501    
3502      if (before)
3503      {      {
3504        user_search_path = strdup (search_dir);        LT_DLMUTEX_LOCK ();
3505        if (!user_search_path)        if ((before < user_search_path)
3506              || (before >= user_search_path + LT_STRLEN (user_search_path)))
3507          {          {
3508            last_error = LT_DLSTRERROR (NO_MEMORY);            LT_DLMUTEX_UNLOCK ();
3509            ++errors;            LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
3510              return 1;
3511          }          }
3512          LT_DLMUTEX_UNLOCK ();
3513      }      }
   else  
     {  
       size_t len = strlen (user_search_path) + 1 + strlen (search_dir);  
       char  *new_search_path = LT_DLMALLOC (char, 1+ len);  
3514    
3515        if (!new_search_path)    if (search_dir && *search_dir)
3516        {
3517          LT_DLMUTEX_LOCK ();
3518          if (lt_dlpath_insertdir (&user_search_path,
3519                                   (char *) before, search_dir) != 0)
3520          {          {
           MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  
3521            ++errors;            ++errors;
3522          }          }
3523        else        LT_DLMUTEX_UNLOCK ();
         {  
           sprintf (new_search_path, "%s%c%s", user_search_path,  
                    LT_PATHSEP_CHAR, search_dir);  
   
           LT_DLMEM_REASSIGN (user_search_path, new_search_path);  
         }  
3524      }      }
   MUTEX_UNLOCK ();  
3525    
3526    return errors;    return errors;
3527  }  }
# Line 2662  int Line 3530  int
3530  lt_dlsetsearchpath (search_path)  lt_dlsetsearchpath (search_path)
3531       const char *search_path;       const char *search_path;
3532  {  {
3533    int errors = 0;    int   errors      = 0;
3534    
3535    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
3536    LT_DLFREE (user_search_path);    LT_DLFREE (user_search_path);
3537    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
3538    
3539    if (!search_path || !strlen (search_path))    if (!search_path || !LT_STRLEN (search_path))
3540      {      {
3541        return errors;        return errors;
3542      }      }
3543    
3544    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
3545    user_search_path = strdup (search_path);    if (canonicalize_path (search_path, &user_search_path) != 0)
3546    if (!user_search_path)      ++errors;
3547      {    LT_DLMUTEX_UNLOCK ();
       ++errors;  
     }  
   MUTEX_UNLOCK ();  
3548    
3549    return errors;    return errors;
3550  }  }
# Line 2689  lt_dlgetsearchpath () Line 3554  lt_dlgetsearchpath ()
3554  {  {
3555    const char *saved_path;    const char *saved_path;
3556    
3557    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
3558    saved_path = user_search_path;    saved_path = user_search_path;
3559    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
3560    
3561    return saved_path;    return saved_path;
3562  }  }
# Line 2704  lt_dlmakeresident (handle) Line 3569  lt_dlmakeresident (handle)
3569    
3570    if (!handle)    if (!handle)
3571      {      {
3572        MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3573        ++errors;        ++errors;
3574      }      }
3575    else    else
# Line 2721  lt_dlisresident        (handle) Line 3586  lt_dlisresident        (handle)
3586  {  {
3587    if (!handle)    if (!handle)
3588      {      {
3589        MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3590        return -1;        return -1;
3591      }      }
3592    
# Line 2739  lt_dlgetinfo (handle) Line 3604  lt_dlgetinfo (handle)
3604  {  {
3605    if (!handle)    if (!handle)
3606      {      {
3607        MUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE));
3608        return 0;        return 0;
3609      }      }
3610    
# Line 2750  lt_dlhandle Line 3615  lt_dlhandle
3615  lt_dlhandle_next (place)  lt_dlhandle_next (place)
3616       lt_dlhandle place;       lt_dlhandle place;
3617  {  {
3618    return place ? place->next : (lt_dlhandle) 0;    return place ? place->next : handles;
3619  }  }
3620    
3621  int  int
# Line 2761  lt_dlforeach (func, data) Line 3626  lt_dlforeach (func, data)
3626    int errors = 0;    int errors = 0;
3627    lt_dlhandle cur;    lt_dlhandle cur;
3628    
3629    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
3630    
3631    cur = handles;    cur = handles;
3632    while (cur)    while (cur)
# Line 2776  lt_dlforeach (func, data) Line 3641  lt_dlforeach (func, data)
3641          }          }
3642      }      }
3643    
3644    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
3645    
3646    return errors;    return errors;
3647  }  }
# Line 2784  lt_dlforeach (func, data) Line 3649  lt_dlforeach (func, data)
3649  lt_dlcaller_id  lt_dlcaller_id
3650  lt_dlcaller_register ()  lt_dlcaller_register ()
3651  {  {
3652    static int last_caller_id = -1;    static lt_dlcaller_id last_caller_id = 0;
3653    int result;    int result;
3654    
3655    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
3656    result = ++last_caller_id;    result = ++last_caller_id;
3657    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
3658    
3659    return result;    return result;
3660  }  }
3661    
 #define N_ELEMENTS(a)   (sizeof(a) / sizeof(*(a)))  
   
3662  lt_ptr  lt_ptr
3663  lt_dlcaller_set_data (key, handle, data)  lt_dlcaller_set_data (key, handle, data)
3664       lt_dlcaller_id key;       lt_dlcaller_id key;
# Line 2808  lt_dlcaller_set_data (key, handle, data) Line 3671  lt_dlcaller_set_data (key, handle, data)
3671    
3672    /* This needs to be locked so that the caller data can be updated    /* This needs to be locked so that the caller data can be updated
3673       simultaneously by different threads.  */       simultaneously by different threads.  */
3674    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
3675    
3676    if (handle->caller_data)    if (handle->caller_data)
3677      n_elements = N_ELEMENTS (handle->caller_data);      while (handle->caller_data[n_elements].key)
3678          ++n_elements;
3679    
3680    for (i = 0; i < n_elements; ++i)    for (i = 0; i < n_elements; ++i)
3681      {      {
# Line 2823  lt_dlcaller_set_data (key, handle, data) Line 3687  lt_dlcaller_set_data (key, handle, data)
3687      }      }
3688    
3689    /* Ensure that there is enough room in this handle's caller_data    /* Ensure that there is enough room in this handle's caller_data
3690       array to accept a new element.  */       array to accept a new element (and an empty end marker).  */
3691    if (i == n_elements)    if (i == n_elements)
3692      {      {
3693        lt_caller_data *temp        lt_caller_data *temp
3694          = LT_DLREALLOC (lt_caller_data, handle->caller_data, 1+ n_elements);          = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements);
3695    
3696        if (temp == 0)        if (!temp)
3697          {          {
3698            MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));            stale = 0;
           stale =  (lt_ptr) 0;  
3699            goto done;            goto done;
3700          }          }
3701        else  
3702          {        handle->caller_data = temp;
           handle->caller_data = temp;  
         }  
3703    
3704        /* We only need this if we needed to allocate a new caller_data.  */        /* We only need this if we needed to allocate a new caller_data.  */
3705        handle->caller_data[i].key  = key;        handle->caller_data[i].key  = key;
3706          handle->caller_data[1+ i].key = 0;
3707      }      }
3708    
3709    handle->caller_data[i].data = data;    handle->caller_data[i].data = data;
3710    
3711   done:   done:
3712    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
3713    
3714    return stale;    return stale;
3715  }  }
# Line 2858  lt_dlcaller_get_data  (key, handle) Line 3720  lt_dlcaller_get_data  (key, handle)
3720       lt_dlhandle handle;       lt_dlhandle handle;
3721  {  {
3722    lt_ptr result = (lt_ptr) 0;    lt_ptr result = (lt_ptr) 0;
   int n_elements = 0;  
3723    
3724    /* This needs to be locked so that the caller data isn't updated by    /* This needs to be locked so that the caller data isn't updated by
3725       another thread part way through this function.  */       another thread part way through this function.  */
3726    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
   
   if (handle->caller_data)  
     n_elements = N_ELEMENTS (handle->caller_data);  
3727    
3728    /* Locate the index of the element with a matching KEY.  */    /* Locate the index of the element with a matching KEY.  */
3729    {    {
3730      int i;      int i;
3731      for (i = 0; i < n_elements; ++i)      for (i = 0; handle->caller_data[i].key; ++i)
3732        {        {
3733          if (handle->caller_data[i].key == key)          if (handle->caller_data[i].key == key)
3734            {            {
# Line 2880  lt_dlcaller_get_data  (key, handle) Line 3738  lt_dlcaller_get_data  (key, handle)
3738        }        }
3739    }    }
3740    
3741    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
3742    
3743    return result;    return result;
3744  }  }
# Line 2904  lt_dlloader_add (place, dlloader, loader Line 3762  lt_dlloader_add (place, dlloader, loader
3762        || (dlloader->module_close == 0)        || (dlloader->module_close == 0)
3763        || (dlloader->find_sym == 0))        || (dlloader->find_sym == 0))
3764      {      {
3765        MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
3766        return 1;        return 1;
3767      }      }
3768    
3769    /* Create a new dlloader node with copies of the user callbacks.  */    /* Create a new dlloader node with copies of the user callbacks.  */
3770    node = LT_DLMALLOC (lt_dlloader, 1);    node = LT_EMALLOC (lt_dlloader, 1);
3771    if (node == 0)    if (!node)
3772      {      return 1;
       MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));  
       return 1;  
     }  
3773    
3774    node->next            = 0;    node->next            = 0;
3775    node->loader_name     = loader_name;    node->loader_name     = loader_name;
# Line 2925  lt_dlloader_add (place, dlloader, loader Line 3780  lt_dlloader_add (place, dlloader, loader
3780    node->find_sym        = dlloader->find_sym;    node->find_sym        = dlloader->find_sym;
3781    node->dlloader_data   = dlloader->dlloader_data;    node->dlloader_data   = dlloader->dlloader_data;
3782    
3783    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
3784    if (!loaders)    if (!loaders)
3785      {      {
3786        /* If there are no loaders, NODE becomes the list! */        /* If there are no loaders, NODE becomes the list! */
# Line 2958  lt_dlloader_add (place, dlloader, loader Line 3813  lt_dlloader_add (place, dlloader, loader
3813    
3814        if (ptr->next != place)        if (ptr->next != place)
3815          {          {
3816            last_error = LT_DLSTRERROR (INVALID_LOADER);            LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
3817            ++errors;            ++errors;
3818          }          }
3819        else        else
# Line 2969  lt_dlloader_add (place, dlloader, loader Line 3824  lt_dlloader_add (place, dlloader, loader
3824          }          }
3825      }      }
3826    
3827    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
3828    
3829    return errors;    return errors;
3830  }  }
# Line 2984  lt_dlloader_remove (loader_name) Line 3839  lt_dlloader_remove (loader_name)
3839    
3840    if (!place)    if (!place)
3841      {      {
3842        MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
3843        return 1;        return 1;
3844      }      }
3845    
3846    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
3847    
3848    /* Fail if there are any open modules which use this loader. */    /* Fail if there are any open modules which use this loader. */
3849    for  (handle = handles; handle; handle = handle->next)    for  (handle = handles; handle; handle = handle->next)
3850      {      {
3851        if (handle->loader == place)        if (handle->loader == place)
3852          {          {
3853            MUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));            LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER));
3854            ++errors;            ++errors;
3855            goto done;            goto done;
3856          }          }
# Line 3030  lt_dlloader_remove (loader_name) Line 3885  lt_dlloader_remove (loader_name)
3885    LT_DLFREE (place);    LT_DLFREE (place);
3886    
3887   done:   done:
3888    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
3889    
3890    return errors;    return errors;
3891  }  }
# Line 3041  lt_dlloader_next (place) Line 3896  lt_dlloader_next (place)
3896  {  {
3897    lt_dlloader *next;    lt_dlloader *next;
3898    
3899    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
3900    next = place ? place->next : loaders;    next = place ? place->next : loaders;
3901    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
3902    
3903    return next;    return next;
3904  }  }
# Line 3056  lt_dlloader_name (place) Line 3911  lt_dlloader_name (place)
3911    
3912    if (place)    if (place)
3913      {      {
3914        MUTEX_LOCK ();        LT_DLMUTEX_LOCK ();
3915        name = place ? place->loader_name : 0;        name = place ? place->loader_name : 0;
3916        MUTEX_UNLOCK ();        LT_DLMUTEX_UNLOCK ();
3917      }      }
3918    else    else
3919      {      {
3920        MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
3921      }      }
3922    
3923    return name;    return name;
# Line 3076  lt_dlloader_data (place) Line 3931  lt_dlloader_data (place)
3931    
3932    if (place)    if (place)
3933      {      {
3934        MUTEX_LOCK ();        LT_DLMUTEX_LOCK ();
3935        data = place ? &(place->dlloader_data) : 0;        data = place ? &(place->dlloader_data) : 0;
3936        MUTEX_UNLOCK ();        LT_DLMUTEX_UNLOCK ();
3937      }      }
3938    else    else
3939      {      {
3940        MUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));        LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
3941      }      }
3942    
3943    return data;    return data;
# Line 3094  lt_dlloader_find (loader_name) Line 3949  lt_dlloader_find (loader_name)
3949  {  {
3950    lt_dlloader *place = 0;    lt_dlloader *place = 0;
3951    
3952    MUTEX_LOCK ();    LT_DLMUTEX_LOCK ();
3953    for (place = loaders; place; place = place->next)    for (place = loaders; place; place = place->next)
3954      {      {
3955        if (strcmp (place->loader_name, loader_name) == 0)        if (strcmp (place->loader_name, loader_name) == 0)
# Line 3102  lt_dlloader_find (loader_name) Line 3957  lt_dlloader_find (loader_name)
3957            break;            break;
3958          }          }
3959      }      }
3960    MUTEX_UNLOCK ();    LT_DLMUTEX_UNLOCK ();
3961    
3962    return place;    return place;
3963  }  }

Legend:
Removed from v.1.134.2.1  
changed lines
  Added in v.1.134.2.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26