--- 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.h.orig Fri May 25 12:47:59 2001 +++ libltdl/ltdl.h Fri Jun 8 14:12:16 2001 @@ -146,10 +146,14 @@ extern int lt_dlinit LT_PARAMS((void)); extern int lt_dlexit LT_PARAMS((void)); -/* Module search path manipultation. */ +/* Module search path manipulation. */ extern int lt_dladdsearchdir LT_PARAMS((const char *search_dir)); extern int lt_dlsetsearchpath LT_PARAMS((const char *search_path)); extern const char *lt_dlgetsearchpath LT_PARAMS((void)); +extern int lt_dlforeachfile LT_PARAMS(( + const char *search_path, + int (*func) (const char *filename, lt_ptr data), + lt_ptr data)); /* Portable libltdl versions of the system dlopen() API. */ extern lt_dlhandle lt_dlopen LT_PARAMS((const char *filename)); @@ -275,8 +279,8 @@ extern const char *lt_dlloader_name LT_PARAMS((lt_dlloader *place)); extern lt_user_data *lt_dlloader_data LT_PARAMS((lt_dlloader *place)); extern int lt_dlloader_add LT_PARAMS((lt_dlloader *place, - const struct lt_user_dlloader *dlloader, - const char *loader_name)); + const struct lt_user_dlloader *dlloader, + const char *loader_name)); extern int lt_dlloader_remove LT_PARAMS(( const char *loader_name)); --- libltdl/ltdl.c.orig Fri May 25 12:48:07 2001 +++ libltdl/ltdl.c Fri Jun 8 14:23:33 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 int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1, + lt_ptr data2)); + +static int foreach_dirinpath LT_PARAMS((const char *search_path, + const char *base_name, + foreach_callback_func *func, + lt_ptr data1, lt_ptr data2)); + +static int find_file_callback LT_PARAMS((char *filename, lt_ptr data, + lt_ptr ignored)); +static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data, + lt_ptr ignored)); +static int foreachfile_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; } -static lt_ptr -find_file (basename, search_path, pdir, handle) - const char *basename; +/* 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 int +foreach_dirinpath (search_path, base_name, func, data1, data2) const char *search_path; - char **pdir; - lt_dlhandle *handle; -{ - /* 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; + const char *base_name; + foreach_callback_func *func; + lt_ptr data1; + lt_ptr data2; +{ + int result = 0; + int filenamesize = 0; + int lenbase = LT_DLSTRLEN (base_name); + char *filename, *canonical, *next; MUTEX_LOCK (); @@ -1674,35 +1735,27 @@ next = canonical; while (next) { - int lendir; - char *cur = next; + char *cur = next; + int lendir; next = strchr (cur, LT_PATHSEP_CHAR); if (!next) - { - next = cur + strlen (cur); - } + next = cur + strlen (cur); lendir = next - cur; if (*next == LT_PATHSEP_CHAR) - { - ++next; - } + ++next; else - { - next = 0; - } + next = 0; if (lendir == 0) - { - continue; - } + continue; - if (lendir + 1 + lenbase >= filenamesize) + if (lendir +1 +lenbase >= filenamesize) { LT_DLFREE (filename); - filenamesize = lendir + 1 + lenbase + 1; - filename = LT_DLMALLOC (char, filenamesize); + filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */ + filename = LT_DLMALLOC (char, filenamesize); if (!filename) { @@ -1711,56 +1764,108 @@ } } - strncpy(filename, cur, lendir); - if (filename[lendir-1] != '/') - { - filename[lendir++] = '/'; - } - strcpy(filename+lendir, basename); - if (handle) + strncpy (filename, cur, lendir); + if (filename[lendir -1] != '/') + filename[lendir++] = '/'; + if (base_name && *base_name) + strcpy (filename +lendir, base_name); + + if ((result = (*func) (filename, data1, data2))) { - if (tryall_dlopen (handle, filename) == 0) - { - result = (lt_ptr) handle; - goto cleanup; - } + break; } - else - { - FILE *file = fopen (filename, LT_READTEXT_MODE); - if (file) - { - LT_DLFREE (*pdir); + } - filename[lendir] = '\0'; - *pdir = strdup(filename); - if (!*pdir) - { - /* We could have even avoided the strdup, - but there would be some memory overhead. */ - *pdir = filename; - filename = 0; - } + cleanup: + LT_DLFREE (canonical); + LT_DLFREE (filename); - result = (lt_ptr) file; - goto cleanup; - } + MUTEX_UNLOCK (); + + return result; +} + +/* If FILEPATH can be opened, store the name of the directory component + in DATA1, and the opened FILE* structure address in DATA2. Otherwise + DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */ +static int +find_file_callback (filename, data1, data2) + char *filename; + lt_ptr data1; + lt_ptr data2; +{ + char **pdir = (char **) data1; + FILE **pfile = (FILE **) data2; + int is_done = 0; + + *pfile = fopen (filename, LT_READTEXT_MODE); + + if (*pfile) + { + char *dirend = strrchr (filename, '/'); + + LT_DLFREE (*pdir); + *dirend = '\0'; + *pdir = strdup (filename); + if (!*pdir) + { + /* We could have even avoided the strdup, + but there would be some memory overhead. */ + *pdir = filename; + filename = 0; /* prevent the foreach function from freeing */ } + is_done = 1; + } + else + { + MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); } - MUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + return is_done; +} - 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; +{ + FILE *file = 0; - MUTEX_UNLOCK (); + foreach_dirinpath (search_path, base_name, find_file_callback, pdir, &file); - return result; + return file; +} + +static int +find_handle_callback (filename, data, ignored) + char *filename; + lt_ptr data; + lt_ptr ignored; +{ + lt_dlhandle *handle = (lt_dlhandle *) data; + int is_done = 0; + + if (tryall_dlopen (handle, filename) == 0) + { + is_done = 1; + } + + return is_done; +} + +static lt_dlhandle * +find_handle (search_path, base_name, handle) + const char *search_path; + const char *base_name; + lt_dlhandle *handle; +{ + foreach_dirinpath (search_path, base_name, find_handle_callback, handle, 0); + return handle; } static int -load_deplibs(handle, deplibs) +load_deplibs (handle, deplibs) lt_dlhandle handle; char *deplibs; { @@ -1933,7 +2038,7 @@ } static int -unload_deplibs(handle) +unload_deplibs (handle) lt_dlhandle handle; { int i; @@ -1961,7 +2066,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 +2114,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 +2155,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 +2167,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 +2194,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 +2203,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 +2215,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 +2223,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 +2417,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 +2540,120 @@ 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 int +foreachfile_callback (dirname, data1, data2) + char *dirname; + lt_ptr data1; + lt_ptr data2; +{ + int (*func) LT_PARAMS((const char *filename, lt_ptr data2)) + = (int (*) LT_PARAMS((const char *filename, 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))) + { + /* Don't try to use `.' or `..' as useful filenames. */ + 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); + + /* Call the user function for this FILENAME. */ + if ((*func) (filename, data2)) + { + break; + } + } + + cleanup: + LT_DLFREE (filename); + closedir (dirp); + + MUTEX_UNLOCK (); + + return 0; +} + +int +lt_dlforeachfile (search_path, func, data) + const char *search_path; + int (*func) LT_PARAMS ((const char *filename, lt_ptr data)); + lt_ptr data; +{ + int is_done = 0; + + if (search_path) + { + /* If a specific path was passed, search only the directories + listed in it. */ + is_done = foreach_dirinpath (search_path, 0, + foreachfile_callback, func, data); + } + else + { + /* Otherwise search the default paths. */ + is_done = foreach_dirinpath (user_search_path, 0, + foreachfile_callback, func, data); + if (!is_done) + { + is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0, + foreachfile_callback, func, data); + } + +#ifdef LTDL_SHLIBPATH_VAR + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0, + foreachfile_callback, func, data); + } +#endif +#ifdef LTDL_SYSSEARCHPATH + if (!is_done) + { + is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0, + foreachfile_callback, func, data); + } +#endif + } + + return is_done; +} + int lt_dlclose (handle) lt_dlhandle handle; @@ -2525,16 +2742,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) {