--- ltdl.m4.orig Fri May 25 15:12:32 2001 +++ ltdl.m4 Fri May 25 15:13:48 2001 @@ -20,7 +20,7 @@ ## configuration script generated by Autoconf, you may include it under ## the same distribution terms that you use for the rest of that program. -# serial 2 AC_LIB_LTDL +# serial 3 AC_LIB_LTDL # AC_LIB_LTDL # ----------- @@ -32,6 +32,7 @@ # Perform all the checks necessary for compilation of the ltdl objects # -- including compiler checks (above) and header checks (below). AC_REQUIRE([AC_HEADER_STDC])dnl +AC_REQUIRE([AC_HEADER_DIRENT])dnl AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl AC_CHECK_HEADERS(malloc.h memory.h stdlib.h stdio.h ctype.h dl.h sys/dl.h dld.h) --- libltdl/ltdl.c.orig Fri May 25 12:48:07 2001 +++ libltdl/ltdl.c Thu May 31 15:04:12 2001 @@ -57,8 +57,27 @@ # include #endif +#if HAVE_DIRENT_H +# include +# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name)) +#else +# define dirent direct +# define LT_D_NAMLEN(dirent) ((dirent)->d_namlen) +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +#endif + #include "ltdl.h" +#define LT_DLSTRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0) + @@ -814,7 +833,7 @@ { /* Append a `.' to stop Windows from adding an implicit `.dll' extension. */ - searchname = LT_DLMALLOC (char, 2+ strlen (filename)); + searchname = LT_DLMALLOC (char, 2+ LT_DLSTRLEN (filename)); if (!searchname) { MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); @@ -1262,6 +1281,47 @@ /* --- DYNAMIC MODULE LOADING --- */ +/* The type of a function used at each iteration of foreach_dirinpath(). */ +typedef lt_ptr foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1, + lt_ptr data2)); + +static lt_ptr foreach_dirinpath LT_PARAMS((const char *search_path, + const char *base_name, + foreach_callback_func *func, + lt_ptr data1, lt_ptr data2)); + +static lt_ptr find_file_callback LT_PARAMS((char *filename, lt_ptr data, + lt_ptr ignored)); +static lt_ptr find_handle_callback LT_PARAMS((char *filename, lt_ptr data, + lt_ptr ignored)); +static lt_ptr openall_callback LT_PARAMS((char *filename, lt_ptr data1, + lt_ptr data2)); + + +static char *canonicalize_path LT_PARAMS((const char *path)); +static FILE *find_file LT_PARAMS((const char *search_path, + const char *base_name, + char **pdir)); +static lt_dlhandle *find_handle LT_PARAMS((const char *search_path, + const char *base_name, + lt_dlhandle *handle)); +static int find_module LT_PARAMS((lt_dlhandle *handle, + const char *dir, + const char *libdir, + const char *dlname, + const char *old_name, + int installed)); +static int free_vars LT_PARAMS((char *dlname, char *oldname, + char *libdir, char *deplibs)); +static int load_deplibs LT_PARAMS((lt_dlhandle handle, + char *deplibs)); +static int trim LT_PARAMS((char **dest, + const char *str)); +static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle, + const char *filename)); +static int unload_deplibs LT_PARAMS((lt_dlhandle handle)); + + static char *user_search_path= 0; static lt_dlloader *loaders = 0; static lt_dlhandle handles = 0; @@ -1561,7 +1621,7 @@ /* try to open the not-installed module */ if (!installed) { - len = (dir ? strlen (dir) : 0) + strlen (objdir) + strlen (dlname); + len = LT_DLSTRLEN (dir) + strlen (objdir) + strlen (dlname); filename = LT_DLMALLOC (char, 1+ len); if (!filename) @@ -1591,7 +1651,7 @@ /* maybe it was moved to another directory */ { - len = (dir ? strlen (dir) : 0) + strlen (dlname); + len = LT_DLSTRLEN (dir) + strlen (dlname); filename = LT_DLMALLOC (char, 1+ len); if (dir) @@ -1616,7 +1676,7 @@ return 1; } -static char* +static char * canonicalize_path (path) const char *path; { @@ -1639,22 +1699,23 @@ return canonical; } +/* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element + of SEARCH_PATH and a copy of DATA, until FUNC returns non-zero or + all elements are exhausted. If BASE_NAME is non-NULL, it is appended + to each SEARCH_PATH element (with a separating '/' added if + necessary) before FUNC is called. */ static lt_ptr -find_file (basename, search_path, pdir, handle) - const char *basename; +foreach_dirinpath (search_path, base_name, func, data1, data2) const char *search_path; - char **pdir; - lt_dlhandle *handle; + const char *base_name; + foreach_callback_func *func; + lt_ptr data1; + lt_ptr data2; { - /* When handle != NULL search a library, otherwise a file - return NULL on failure, otherwise the file/handle. */ - lt_ptr result = 0; - char *filename = 0; - int filenamesize= 0; - int lenbase = strlen (basename); - char *canonical = 0; - char *next = 0; + int filenamesize = 0; + int lenbase = LT_DLSTRLEN (base_name); + char *filename, *canonical, *next; MUTEX_LOCK (); @@ -1674,34 +1735,26 @@ next = canonical; while (next) { - int lendir; char *cur = next; + int lendir; next = strchr (cur, LT_PATHSEP_CHAR); if (!next) - { next = cur + strlen (cur); - } lendir = next - cur; if (*next == LT_PATHSEP_CHAR) - { ++next; - } else - { next = 0; - } if (lendir == 0) - { continue; - } - if (lendir + 1 + lenbase >= filenamesize) + if (lendir +1 +lenbase >= filenamesize) { LT_DLFREE (filename); - filenamesize = lendir + 1 + lenbase + 1; + filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */ filename = LT_DLMALLOC (char, filenamesize); if (!filename) @@ -1711,29 +1764,44 @@ } } - strncpy(filename, cur, lendir); - if (filename[lendir-1] != '/') - { + strncpy (filename, cur, lendir); + if (filename[lendir -1] != '/') filename[lendir++] = '/'; - } - strcpy(filename+lendir, basename); - if (handle) - { - if (tryall_dlopen (handle, filename) == 0) + if (base_name && *base_name) + strcpy (filename +lendir, base_name); + + if ((result = (*func) (filename, data1, data2))) { - result = (lt_ptr) handle; - goto cleanup; + break; } } - else - { + + cleanup: + LT_DLFREE (canonical); + LT_DLFREE (filename); + + MUTEX_UNLOCK (); + + return result; +} + +static lt_ptr +find_file_callback (filename, data, ignored) + char *filename; + lt_ptr data; + lt_ptr ignored; +{ + char **pdir = (char **) data; FILE *file = fopen (filename, LT_READTEXT_MODE); + lt_ptr result = 0; + if (file) { - LT_DLFREE (*pdir); + char *dirend = strrchr (filename, '/'); - filename[lendir] = '\0'; - *pdir = strdup(filename); + LT_DLFREE (*pdir); + *dirend = '\0'; + *pdir = strdup (filename); if (!*pdir) { /* We could have even avoided the strdup, @@ -1741,26 +1809,55 @@ *pdir = filename; filename = 0; } - result = (lt_ptr) file; - goto cleanup; - } } + else + { + MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); } - MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + return result; +} - cleanup: - LT_DLFREE (filename); - LT_DLFREE (canonical); +static FILE * +find_file (search_path, base_name, pdir) + const char *search_path; + const char *base_name; + char **pdir; +{ + return (FILE *) foreach_dirinpath (search_path, base_name, + find_file_callback, pdir, 0); +} - MUTEX_UNLOCK (); +static lt_ptr +find_handle_callback (filename, data, ignored) + char *filename; + lt_ptr data; + lt_ptr ignored; +{ + lt_dlhandle *handle = (lt_dlhandle *) data; + lt_ptr result = 0; + + if (tryall_dlopen (handle, filename) == 0) + { + result = (lt_ptr) handle; + } return result; } +static lt_dlhandle * +find_handle (search_path, base_name, handle) + const char *search_path; + const char *base_name; + lt_dlhandle *handle; +{ + return (lt_dlhandle *) foreach_dirinpath (search_path, base_name, + find_handle_callback, handle, 0); +} + static int -load_deplibs(handle, deplibs) +load_deplibs (handle, deplibs) lt_dlhandle handle; char *deplibs; { @@ -1933,7 +2030,7 @@ } static int -unload_deplibs(handle) +unload_deplibs (handle) lt_dlhandle handle; { int i; @@ -1961,7 +2058,7 @@ /* remove the leading and trailing "'" from str and store the result in dest */ const char *end = strrchr (str, '\''); - int len = strlen (str); + int len = LT_DLSTRLEN (str); char *tmp; LT_DLFREE (*dest); @@ -2009,7 +2106,7 @@ lt_dlhandle handle = 0, newhandle; const char *ext; const char *saved_error; - char *canonical = 0, *basename = 0, *dir = 0, *name = 0; + char *canonical = 0, *base_name = 0, *dir = 0, *name = 0; MUTEX_GETERROR (saved_error); @@ -2050,11 +2147,11 @@ /* If the canonical module name is a path (relative or absolute) then split it into a directory part and a name part. */ - basename = strrchr (canonical, '/'); - if (basename) + base_name = strrchr (canonical, '/'); + if (base_name) { - ++basename; - dir = LT_DLMALLOC (char, basename - canonical + 1); + ++base_name; + dir = LT_DLMALLOC (char, base_name - canonical + 1); if (!dir) { MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); @@ -2062,16 +2159,16 @@ goto cleanup; } - strncpy (dir, canonical, basename - canonical); - dir[basename - canonical] = '\0'; + strncpy (dir, canonical, base_name - canonical); + dir[base_name - canonical] = '\0'; } else { - basename = canonical; + base_name = canonical; } /* Check whether we are opening a libtool module (.la extension). */ - ext = strrchr(basename, '.'); + ext = strrchr(base_name, '.'); if (ext && strcmp(ext, ".la") == 0) { /* this seems to be a libtool module */ @@ -2089,7 +2186,7 @@ int installed = 1; /* extract the module name from the file name */ - name = LT_DLMALLOC (char, ext - basename + 1); + name = LT_DLMALLOC (char, ext - base_name + 1); if (!name) { MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); @@ -2098,11 +2195,11 @@ } /* canonicalize the module name */ - for (i = 0; i < ext - basename; ++i) + for (i = 0; i < ext - base_name; ++i) { - if (isalnum ((int)(basename[i]))) + if (isalnum ((int)(base_name[i]))) { - name[i] = basename[i]; + name[i] = base_name[i]; } else { @@ -2110,7 +2207,7 @@ } } - name[ext - basename] = '\0'; + name[ext - base_name] = '\0'; /* Now try to open the .la file. If there is no directory name component, try to find it first in user_search_path and then other @@ -2118,24 +2215,22 @@ yet found) try opening just the module name as passed. */ if (!dir) { - file = (FILE*) find_file(basename, user_search_path, &dir, 0); + file = find_file (user_search_path, base_name, &dir); if (!file) { - file = (FILE*) find_file(basename, getenv("LTDL_LIBRARY_PATH"), - &dir, 0); + file = find_file (getenv("LTDL_LIBRARY_PATH"), base_name, &dir); } #ifdef LTDL_SHLIBPATH_VAR if (!file) { - file = (FILE*) find_file(basename, getenv(LTDL_SHLIBPATH_VAR), - &dir, 0); + file = find_file (getenv(LTDL_SHLIBPATH_VAR), base_name, &dir); } #endif #ifdef LTDL_SYSSEARCHPATH if (!file) { - file = (FILE*) find_file(basename, sys_search_path, &dir, 0); + file = find_file (sys_search_path, base_name, &dir); } #endif } @@ -2314,15 +2409,15 @@ first in user_search_path and then other prescribed paths. Otherwise (or in any case if the module was not yet found) try opening just the module name as passed. */ - if ((dir || (!find_file (basename, user_search_path, 0, &newhandle) - && !find_file (basename, getenv ("LTDL_LIBRARY_PATH"), - 0, &newhandle) + if ((dir || (!find_handle (user_search_path, base_name, &newhandle) + && !find_handle (getenv ("LTDL_LIBRARY_PATH"), base_name, + &newhandle) #ifdef LTDL_SHLIBPATH_VAR - && !find_file (basename, getenv (LTDL_SHLIBPATH_VAR), - 0, &newhandle) + && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name, + &newhandle) #endif #ifdef LTDL_SYSSEARCHPATH - && !find_file (basename, sys_search_path, 0, &newhandle) + && !find_handle (sys_search_path, base_name, &newhandle) #endif )) && tryall_dlopen (&newhandle, filename)) { @@ -2437,6 +2532,113 @@ return 0; } +/* If there are any files in DIRNAME, try to load them as modules, and if + successful call the verify function passed as DATA1 (with the loaded + module handle and DATA2 as arguments). If that function returns + non-zero, then unload that module, otherwise leave it loaded. */ +static lt_ptr +openall_callback (dirname, data1, data2) + char *dirname; + lt_ptr data1; + lt_ptr data2; +{ + int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data2)) + = (int (*) LT_PARAMS((lt_dlhandle handle, lt_ptr data2))) data1; + + char *filename = 0; + int filenamesize = 0; + int lendir = LT_DLSTRLEN (dirname); + DIR *dirp = opendir (dirname); + struct dirent *direntp; + + if (!dirp) + return 0; + + MUTEX_LOCK (); + + rewinddir (dirp); + while ((direntp = readdir (dirp))) + { + lt_dlhandle module; + + /* Don't try to open `.' or `..' as modules. */ + if ((direntp->d_name[0] == '.') + && (((direntp->d_name[1] == '.') && (direntp->d_name[2] == '\0')) + || (direntp->d_name[1] == '\0'))) + { + continue; + } + + if (lendir +1 +LT_D_NAMLEN(direntp) >= filenamesize) + { + LT_DLFREE (filename); + filenamesize = lendir +1 + LT_D_NAMLEN(direntp) +1; + filename = LT_DLMALLOC (char, filenamesize); + + if (!filename) + { + MUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); + goto cleanup; + } + } + + strcpy (filename, dirname); + if (filename[lendir -1] != '/') + filename[lendir++] = '/'; + strcpy (filename +lendir, direntp->d_name); + + /* See whether it is a loadable module at all. */ + module = lt_dlopen (filename); + if (!module) + continue; + + /* Check that the user function wants to keep the module. */ + if ((*func) (module, data2)) + { + lt_dlclose (module); + continue; + } + } + + cleanup: + LT_DLFREE (filename); + closedir (dirp); + + MUTEX_UNLOCK (); + + return 0; +} + +lt_ptr +lt_dlopenall (search_path, func, data) + const char *search_path; + lt_ptr (*func) LT_PARAMS ((lt_dlhandle handle, lt_ptr data)); + lt_ptr data; +{ + lt_ptr result = 0; + + if (search_path) + { + /* If a specific path was passed, search only the directories + listed in it. */ + result = foreach_dirinpath (search_path, 0, + openall_callback, func, data); + } + else + { + /* Otherwise search the default paths. */ + result = foreach_dirinpath (user_search_path, 0, + openall_callback, func, data); + if (!result) + { + result = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0, + openall_callback, func, data); + } + } + + return result; +} + int lt_dlclose (handle) lt_dlhandle handle; @@ -2525,16 +2727,8 @@ return 0; } - lensym = strlen(symbol); - if (handle->loader->sym_prefix) - { - lensym += strlen(handle->loader->sym_prefix); - } - - if (handle->info.name) - { - lensym += strlen(handle->info.name); - } + lensym = strlen (symbol) + LT_DLSTRLEN (handle->loader->sym_prefix) + + LT_DLSTRLEN (handle->info.name); if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH) { --- libltdl/ltdl.h.orig Fri May 25 12:47:59 2001 +++ libltdl/ltdl.h Fri May 25 15:34:49 2001 @@ -154,6 +154,10 @@ /* Portable libltdl versions of the system dlopen() API. */ extern lt_dlhandle lt_dlopen LT_PARAMS((const char *filename)); extern lt_dlhandle lt_dlopenext LT_PARAMS((const char *filename)); +extern lt_ptr lt_dlopenall LT_PARAMS(( + const char *search_path, + lt_ptr (*func) (lt_dlhandle handle, lt_ptr data), + lt_ptr data)); extern lt_ptr lt_dlsym LT_PARAMS((lt_dlhandle handle, const char *name)); extern const char *lt_dlerror LT_PARAMS((void));