/[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 by gary, Tue Apr 24 22:53:48 2001 UTC revision 1.135 by gary, Tue Jun 26 00:50:38 2001 UTC
# Line 57  Foundation, Inc., 59 Temple Place, Suite Line 57  Foundation, Inc., 59 Temple Place, Suite
57  #  include <memory.h>  #  include <memory.h>
58  #endif  #endif
59    
60    #if HAVE_DIRENT_H
61    #  include <dirent.h>
62    #  define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
63    #else
64    #  define dirent direct
65    #  define LT_D_NAMLEN(dirent) ((dirent)->d_namlen)
66    #  if HAVE_SYS_NDIR_H
67    #    include <sys/ndir.h>
68    #  endif
69    #  if HAVE_SYS_DIR_H
70    #    include <sys/dir.h>
71    #  endif
72    #  if HAVE_NDIR_H
73    #    include <ndir.h>
74    #  endif
75    #endif
76    
77  #include "ltdl.h"  #include "ltdl.h"
78    
79    
# Line 1262  static struct lt_user_dlloader presym = Line 1279  static struct lt_user_dlloader presym =
1279  /* --- DYNAMIC MODULE LOADING --- */  /* --- DYNAMIC MODULE LOADING --- */
1280    
1281    
1282    /* The type of a function used at each iteration of  foreach_dirinpath().  */
1283    typedef int     foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1,
1284                                                     lt_ptr data2));
1285    
1286  static  char           *user_search_path= 0;  static  char           *user_search_path= 0;
1287  static  lt_dlloader    *loaders         = 0;  static  lt_dlloader    *loaders         = 0;
1288  static  lt_dlhandle     handles         = 0;  static  lt_dlhandle     handles         = 0;
# Line 1616  find_module (handle, dir, libdir, dlname Line 1637  find_module (handle, dir, libdir, dlname
1637    return 1;    return 1;
1638  }  }
1639    
1640  static char*  static char *
1641  canonicalize_path (path)  canonicalize_path (path)
1642       const char *path;       const char *path;
1643  {  {
# Line 1639  canonicalize_path (path) Line 1660  canonicalize_path (path)
1660    return canonical;    return canonical;
1661  }  }
1662    
1663  static lt_ptr  /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
1664  find_file (basename, search_path, pdir, handle)     of SEARCH_PATH and a copy of DATA, until FUNC returns non-zero or
1665       const char *basename;     all elements are exhausted.  If BASE_NAME is non-NULL, it is appended
1666       to each SEARCH_PATH element (with a separating '/' added if
1667       necessary) before FUNC is called.  */
1668    static int
1669    foreach_dirinpath (search_path, base_name, func, data1, data2)
1670       const char *search_path;       const char *search_path;
1671       char **pdir;       const char *base_name;
1672       lt_dlhandle *handle;       foreach_callback_func *func;
1673  {       lt_ptr data1;
1674    /* When handle != NULL search a library, otherwise a file       lt_ptr data2;
1675       return NULL on failure, otherwise the file/handle.  */  {
1676      int   result          = 0;
1677    lt_ptr    result      = 0;    int   filenamesize    = 0;
1678    char     *filename    = 0;    int   lenbase         = base_name ? strlen (base_name) : 0;
1679    int       filenamesize= 0;    char *filename, *canonical, *next;
   int       lenbase     = strlen (basename);  
   char     *canonical   = 0;  
   char     *next        = 0;  
1680    
1681    MUTEX_LOCK ();    MUTEX_LOCK ();
1682    
# Line 1674  find_file (basename, search_path, pdir, Line 1696  find_file (basename, search_path, pdir,
1696    next = canonical;    next = canonical;
1697    while (next)    while (next)
1698      {      {
1699        int lendir;        char *cur     = next;
1700        char *cur = next;        int   lendir;
1701    
1702        next = strchr (cur, LT_PATHSEP_CHAR);        next = strchr (cur, LT_PATHSEP_CHAR);
1703        if (!next)        if (!next)
1704          {          next = cur + strlen (cur);
           next = cur + strlen (cur);  
         }  
1705    
1706        lendir = next - cur;        lendir = next - cur;
1707        if (*next == LT_PATHSEP_CHAR)        if (*next == LT_PATHSEP_CHAR)
1708          {          ++next;
           ++next;  
         }  
1709        else        else
1710          {          next = 0;
           next = 0;  
         }  
1711    
1712        if (lendir == 0)        if (lendir == 0)
1713          {          continue;
           continue;  
         }  
1714    
1715        if (lendir + 1 + lenbase >= filenamesize)        if (lendir +1 +lenbase >= filenamesize)
1716          {          {
1717            LT_DLFREE (filename);            LT_DLFREE (filename);
1718            filenamesize = lendir + 1 + lenbase + 1;            filenamesize  = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */
1719            filename = LT_DLMALLOC (char, filenamesize);            filename      = LT_DLMALLOC (char, filenamesize);
1720    
1721            if (!filename)            if (!filename)
1722              {              {
# Line 1711  find_file (basename, search_path, pdir, Line 1725  find_file (basename, search_path, pdir,
1725              }              }
1726          }          }
1727    
1728        strncpy(filename, cur, lendir);        strncpy (filename, cur, lendir);
1729        if (filename[lendir-1] != '/')        if (filename[lendir -1] != '/')
1730          {          filename[lendir++] = '/';
1731            filename[lendir++] = '/';        if (base_name && *base_name)
1732          }          strcpy (filename +lendir, base_name);
1733        strcpy(filename+lendir, basename);  
1734        if (handle)        if ((result = (*func) (filename, data1, data2)))
1735          {          {
1736            if (tryall_dlopen (handle, filename) == 0)            break;
             {  
               result = (lt_ptr) handle;  
               goto cleanup;  
             }  
1737          }          }
1738        else      }
         {  
           FILE *file = fopen (filename, LT_READTEXT_MODE);  
           if (file)  
             {  
               LT_DLFREE (*pdir);  
1739    
1740                filename[lendir] = '\0';   cleanup:
1741                *pdir = strdup(filename);    LT_DLFREE (canonical);
1742                if (!*pdir)    LT_DLFREE (filename);
                 {  
                   /* We could have even avoided the strdup,  
                      but there would be some memory overhead. */  
                   *pdir = filename;  
                   filename = 0;  
                 }  
1743    
1744                result = (lt_ptr) file;    MUTEX_UNLOCK ();
1745                goto cleanup;    
1746              }    return result;
1747    }
1748    
1749    /* If FILEPATH can be opened, store the name of the directory component
1750       in DATA1, and the opened FILE* structure address in DATA2.  Otherwise
1751       DATA1 is unchanged, but DATA2 is set to a pointer to NULL.  */
1752    static int
1753    find_file_callback (filename, data1, data2)
1754         char *filename;
1755         lt_ptr data1;
1756         lt_ptr data2;
1757    {
1758      char        **pdir    = (char **) data1;
1759      FILE        **pfile   = (FILE **) data2;
1760      int           is_done = 0;
1761    
1762      *pfile = fopen (filename, LT_READTEXT_MODE);
1763    
1764      if (*pfile)
1765        {
1766          char *dirend = strrchr (filename, '/');
1767    
1768          LT_DLFREE (*pdir);
1769          *dirend = '\0';
1770          *pdir = strdup (filename);
1771          if (!*pdir)
1772            {
1773              /* We could have even avoided the strdup,
1774                 but there would be some memory overhead. */
1775              *pdir = filename;
1776              filename = 0; /* prevent the foreach function from freeing */
1777          }          }
1778          is_done = 1;
1779        }
1780      else
1781        {
1782          MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
1783      }      }
1784    
1785    MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));    return is_done;
1786    }
1787    
1788   cleanup:  static FILE *
1789    LT_DLFREE (filename);  find_file (search_path, base_name, pdir)
1790    LT_DLFREE (canonical);       const char *search_path;
1791         const char *base_name;
1792         char **pdir;
1793    {
1794      FILE *file = 0;
1795    
1796    MUTEX_UNLOCK ();    foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file);
1797    
1798    return result;    return file;
1799  }  }
1800    
1801  static int  static int
1802  load_deplibs(handle, deplibs)  find_handle_callback (filename, data, ignored)
1803         char *filename;
1804         lt_ptr data;
1805         lt_ptr ignored;
1806    {
1807      lt_dlhandle  *handle  = (lt_dlhandle *) data;
1808      int           is_done = 0;
1809    
1810      if (tryall_dlopen (handle, filename) == 0)
1811        {
1812          is_done = 1;
1813        }
1814    
1815      return is_done;
1816    }
1817    
1818    static lt_dlhandle *
1819    find_handle (search_path, base_name, handle)
1820         const char *search_path;
1821         const char *base_name;
1822         lt_dlhandle *handle;
1823    {
1824      foreach_dirinpath (search_path, base_name, find_handle_callback, handle, 0);
1825      return handle;
1826    }
1827    
1828    static int
1829    load_deplibs (handle, deplibs)
1830       lt_dlhandle handle;       lt_dlhandle handle;
1831       char *deplibs;       char *deplibs;
1832  {  {
# Line 1933  load_deplibs(handle, deplibs) Line 1999  load_deplibs(handle, deplibs)
1999  }  }
2000    
2001  static int  static int
2002  unload_deplibs(handle)  unload_deplibs (handle)
2003       lt_dlhandle handle;       lt_dlhandle handle;
2004  {  {
2005    int i;    int i;
# Line 2009  lt_dlopen (filename) Line 2075  lt_dlopen (filename)
2075    lt_dlhandle handle = 0, newhandle;    lt_dlhandle handle = 0, newhandle;
2076    const char *ext;    const char *ext;
2077    const char *saved_error;    const char *saved_error;
2078    char  *canonical = 0, *basename = 0, *dir = 0, *name = 0;    char  *canonical = 0, *base_name = 0, *dir = 0, *name = 0;
2079    
2080    MUTEX_GETERROR (saved_error);    MUTEX_GETERROR (saved_error);
2081    
# Line 2050  lt_dlopen (filename) Line 2116  lt_dlopen (filename)
2116    
2117    /* If the canonical module name is a path (relative or absolute)    /* If the canonical module name is a path (relative or absolute)
2118       then split it into a directory part and a name part.  */       then split it into a directory part and a name part.  */
2119    basename = strrchr (canonical, '/');    base_name = strrchr (canonical, '/');
2120    if (basename)    if (base_name)
2121      {      {
2122        ++basename;        ++base_name;
2123        dir = LT_DLMALLOC (char, basename - canonical + 1);        dir = LT_DLMALLOC (char, base_name - canonical + 1);
2124        if (!dir)        if (!dir)
2125          {          {
2126            MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));            MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
# Line 2062  lt_dlopen (filename) Line 2128  lt_dlopen (filename)
2128            goto cleanup;            goto cleanup;
2129          }          }
2130    
2131        strncpy (dir, canonical, basename - canonical);        strncpy (dir, canonical, base_name - canonical);
2132        dir[basename - canonical] = '\0';        dir[base_name - canonical] = '\0';
2133      }      }
2134    else    else
2135      {      {
2136        basename = canonical;        base_name = canonical;
2137      }      }
2138    
2139    /* Check whether we are opening a libtool module (.la extension).  */    /* Check whether we are opening a libtool module (.la extension).  */
2140    ext = strrchr(basename, '.');    ext = strrchr(base_name, '.');
2141    if (ext && strcmp(ext, ".la") == 0)    if (ext && strcmp(ext, ".la") == 0)
2142      {      {
2143        /* this seems to be a libtool module */        /* this seems to be a libtool module */
# Line 2089  lt_dlopen (filename) Line 2155  lt_dlopen (filename)
2155        int       installed = 1;        int       installed = 1;
2156    
2157        /* extract the module name from the file name */        /* extract the module name from the file name */
2158        name = LT_DLMALLOC (char, ext - basename + 1);        name = LT_DLMALLOC (char, ext - base_name + 1);
2159        if (!name)        if (!name)
2160          {          {
2161            MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));            MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
# Line 2098  lt_dlopen (filename) Line 2164  lt_dlopen (filename)
2164          }          }
2165    
2166        /* canonicalize the module name */        /* canonicalize the module name */
2167        for (i = 0; i < ext - basename; ++i)        for (i = 0; i < ext - base_name; ++i)
2168          {          {
2169            if (isalnum ((int)(basename[i])))            if (isalnum ((int)(base_name[i])))
2170              {              {
2171                name[i] = basename[i];                name[i] = base_name[i];
2172              }              }
2173            else            else
2174              {              {
# Line 2110  lt_dlopen (filename) Line 2176  lt_dlopen (filename)
2176              }              }
2177          }          }
2178    
2179        name[ext - basename] = '\0';        name[ext - base_name] = '\0';
2180    
2181      /* 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
2182         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 2118  lt_dlopen (filename) Line 2184  lt_dlopen (filename)
2184         yet found) try opening just the module name as passed.  */         yet found) try opening just the module name as passed.  */
2185        if (!dir)        if (!dir)
2186          {          {
2187            file = (FILE*) find_file(basename, user_search_path, &dir, 0);            file = find_file (user_search_path, base_name, &dir);
2188            if (!file)            if (!file)
2189              {              {
2190                file = (FILE*) find_file(basename, getenv("LTDL_LIBRARY_PATH"),                file = find_file (getenv("LTDL_LIBRARY_PATH"), base_name, &dir);
                                        &dir, 0);  
2191              }              }
2192    
2193  #ifdef LTDL_SHLIBPATH_VAR  #ifdef LTDL_SHLIBPATH_VAR
2194            if (!file)            if (!file)
2195              {              {
2196                file = (FILE*) find_file(basename, getenv(LTDL_SHLIBPATH_VAR),                file = find_file (getenv(LTDL_SHLIBPATH_VAR), base_name, &dir);
                                        &dir, 0);  
2197              }              }
2198  #endif  #endif
2199  #ifdef LTDL_SYSSEARCHPATH  #ifdef LTDL_SYSSEARCHPATH
2200            if (!file)            if (!file)
2201              {              {
2202                file = (FILE*) find_file(basename, sys_search_path, &dir, 0);                file = find_file (sys_search_path, base_name, &dir);
2203              }              }
2204  #endif  #endif
2205          }          }
# Line 2314  lt_dlopen (filename) Line 2378  lt_dlopen (filename)
2378           first in user_search_path and then other prescribed paths.           first in user_search_path and then other prescribed paths.
2379           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
2380           opening just the module name as passed.  */           opening just the module name as passed.  */
2381        if ((dir || (!find_file (basename, user_search_path, 0, &newhandle)        if ((dir || (!find_handle (user_search_path, base_name, &newhandle)
2382                     && !find_file (basename, getenv ("LTDL_LIBRARY_PATH"),                     && !find_handle (getenv ("LTDL_LIBRARY_PATH"), base_name,
2383                                    0, &newhandle)                                      &newhandle)
2384  #ifdef LTDL_SHLIBPATH_VAR  #ifdef LTDL_SHLIBPATH_VAR
2385                     && !find_file (basename, getenv (LTDL_SHLIBPATH_VAR),                     && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name,
2386                                    0, &newhandle)                                      &newhandle)
2387  #endif  #endif
2388  #ifdef LTDL_SYSSEARCHPATH  #ifdef LTDL_SYSSEARCHPATH
2389                     && !find_file (basename, sys_search_path, 0, &newhandle)                     && !find_handle (sys_search_path, base_name, &newhandle)
2390  #endif  #endif
2391                     )) && tryall_dlopen (&newhandle, filename))                     )) && tryall_dlopen (&newhandle, filename))
2392          {          {
# Line 2437  lt_dlopenext (filename) Line 2501  lt_dlopenext (filename)
2501    return 0;    return 0;
2502  }  }
2503    
2504    /* If there are any files in DIRNAME, try to load them as modules, and if
2505       successful call the verify function passed as DATA1 (with the loaded
2506       module handle and DATA2 as arguments).  If that function returns
2507       non-zero, then unload that module, otherwise leave it loaded.  */
2508    static int
2509    foreachfile_callback (dirname, data1, data2)
2510         char *dirname;
2511         lt_ptr data1;
2512         lt_ptr data2;
2513    {
2514      int (*func) LT_PARAMS((const char *filename, lt_ptr data2))
2515            = (int (*) LT_PARAMS((const char *filename, lt_ptr data2))) data1;
2516    
2517      char *filename        = 0;
2518      int   filenamesize    = 0;
2519      int   lendir          = strlen (dirname);
2520      DIR  *dirp            = opendir (dirname);
2521      struct dirent *direntp;
2522    
2523      if (!dirp)
2524        return 0;
2525    
2526      MUTEX_LOCK ();
2527    
2528      rewinddir (dirp);
2529      while ((direntp = readdir (dirp)))
2530        {
2531          /* Don't try to use `.' or `..' as useful filenames.  */
2532          if ((direntp->d_name[0] == '.')
2533              && (((direntp->d_name[1] == '.') && (direntp->d_name[2] == '\0'))
2534                  || (direntp->d_name[1] == '\0')))
2535            {
2536              continue;
2537            }
2538    
2539          if (lendir +1 +LT_D_NAMLEN(direntp) >= filenamesize)
2540            {
2541              LT_DLFREE (filename);
2542              filenamesize  = lendir +1 + LT_D_NAMLEN(direntp) +1;
2543              filename      = LT_DLMALLOC (char, filenamesize);
2544    
2545              if (!filename)
2546                {
2547                  MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
2548                  goto cleanup;
2549                }
2550            }
2551    
2552          strcpy (filename, dirname);
2553          if (filename[lendir -1] != '/')
2554            filename[lendir++] = '/';
2555          strcpy (filename +lendir, direntp->d_name);
2556    
2557          /* Call the user function for this FILENAME.  */
2558          if ((*func) (filename, data2))
2559            {
2560              break;
2561            }
2562        }
2563    
2564     cleanup:
2565      LT_DLFREE (filename);
2566      closedir (dirp);
2567      
2568      MUTEX_UNLOCK ();
2569    
2570      return 0;
2571    }
2572    
2573    int
2574    lt_dlforeachfile (search_path, func, data)
2575         const char *search_path;
2576         int (*func) LT_PARAMS ((const char *filename, lt_ptr data));
2577         lt_ptr data;
2578    {
2579      int is_done = 0;
2580    
2581      if (search_path)
2582        {
2583          /* If a specific path was passed, search only the directories
2584             listed in it.  */
2585          is_done = foreach_dirinpath (search_path, 0,
2586                                       foreachfile_callback, func, data);
2587        }
2588      else
2589        {
2590          /* Otherwise search the default paths.  */
2591          is_done = foreach_dirinpath (user_search_path, 0,
2592                                       foreachfile_callback, func, data);
2593          if (!is_done)
2594            {
2595              is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0,
2596                                           foreachfile_callback, func, data);
2597            }
2598    
2599    #ifdef LTDL_SHLIBPATH_VAR
2600          if (!is_done)
2601            {
2602              is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0,
2603                                           foreachfile_callback, func, data);
2604            }
2605    #endif
2606    #ifdef LTDL_SYSSEARCHPATH
2607          if (!is_done)
2608            {
2609              is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0,
2610                                           foreachfile_callback, func, data);
2611            }
2612    #endif
2613        }
2614    
2615      return is_done;
2616    }
2617    
2618  int  int
2619  lt_dlclose (handle)  lt_dlclose (handle)
2620       lt_dlhandle handle;       lt_dlhandle handle;

Legend:
Removed from v.1.134  
changed lines
  Added in v.1.135

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