? autom4te.cache ? foo ? COPYING ? .cvsapplyrc ? libtool-1.4 ? 1-gary-automake-1-5-made-me-do-it.patch ? .patch_number ? patches ? libtool-1.4-1.4b.diff.gz ? libtool-1.4.tar.gz ? libtool-1.4-1.4b.tar.xdp.gz ? ltdldemo ? INSTALL ? mkinstalldirs ? missing ? 2-gary-ltdl-fix-bogus-file-not-found.patch ? cygwin-patches.tar.bz2 ? libtool-1.4b.tar.gz ? dyld.patch ? install-sh ? cdemo/autom4te.cache ? demo/autom4te.cache ? depdemo/autom4te.cache ? libltdl/autom4te.cache ? libltdl/config-h.in ? mail/accounts2 ? mail/accounts ? mdemo/autom4te.cache ? pdemo/autom4te.cache ? tagdemo/autom4te.cache Index: ChangeLog from Gary V. Vaughan Based on a patch from Marius Vollmer : * NEWS: updated. * ltdl.m4 (AC_LIB_LTDL): Check for unistd.h. * ltdl.c: Include unistd.h if it exists. (LTDL_SEARCHPATH_VAR): Macro to prevent hardcoding "LTDL_LIBRARY_PATH". (LTDL_ARCHIVE_EXT): Macro to prevent hardcoding ".la". (archive_ext): Have only one copy of ".la" in the readonly segment of the compiled library. (find_handle_callback): Don't bother trying to dlopen the file if it doesn't exist. (find_handle): Don't bother searching for files if no search_path was supplied. (file_not_found): A new function to determine whether the last error was due to a file not found condition. (try_dlopen): Renamed from lt_dlopen() and changed to have the same footprint as tryall_dlopen. This involved a minor rewrite of much of the internals of this function. (lt_dlopen): A new function wrapped arounf try_dlopen(). (lt_dlopenext): If a file already has a suitable extension, don't bother adding additional extensions and trying to open those. Tidy up the rest of the code to prevent continued searching with an eventual FILE_NOT_FOUND when a genuine failure earlier in the search process could be legitimately reported. Index: NEWS =================================================================== RCS file: /cvsroot/libtool/libtool/NEWS,v retrieving revision 1.104 diff -u -r1.104 NEWS --- NEWS 2001/08/13 17:25:49 1.104 +++ NEWS 2001/09/02 17:37:23 @@ -3,6 +3,7 @@ New in 1.4d: 2001-??-??; CVS version 1.4c, Libtool team: * Help strings display correctly again. * Better error messages when library linking fails. +* Better error messages from libltdl when loading fails. * Better search path management in libltdl with `lt_dlinsertsearchdir' call. * Support /lib/w32api in recent cygwin releases. * Support cross compilation to mingw. Index: ltdl.m4 =================================================================== RCS file: /cvsroot/libtool/libtool/ltdl.m4,v retrieving revision 1.32 diff -u -r1.32 ltdl.m4 --- ltdl.m4 2001/08/13 17:25:49 1.32 +++ ltdl.m4 2001/09/02 17:37:29 @@ -45,7 +45,7 @@ AC_REQUIRE([AC_LTDL_SYS_DLOPEN_DEPLIBS]) AC_REQUIRE([AC_LTDL_FUNC_ARGZ]) -AC_CHECK_HEADERS([ctype.h errno.h malloc.h memory.h stdlib.h stdio.h]) +AC_CHECK_HEADERS([ctype.h errno.h malloc.h memory.h stdlib.h stdio.h unistd.h]) AC_CHECK_HEADERS([dl.h sys/dl.h dld.h]) AC_CHECK_HEADERS([string.h strings.h], [break]) @@ -246,7 +246,7 @@ [LIBADD_DL= AC_SUBST(LIBADD_DL) AC_LANG_PUSH([C]) -AC_CHECK_LIB([dl], [dlopen], +AC_CHECK_LIB([dl], [dlopen], [AC_DEFINE([HAVE_LIBDL], [1], [Define if you have the libdl library or equivalent.]) LIBADD_DL="-ldl"], @@ -254,10 +254,10 @@ # include #endif ], - [dlopen();], + [dlopen();], [AC_DEFINE(HAVE_LIBDL, 1, [Define if you have the libdl library or equivalent.])], - [AC_CHECK_LIB(svld, dlopen, + [AC_CHECK_LIB(svld, dlopen, [AC_DEFINE(HAVE_LIBDL, 1, [Define if you have the libdl library or equivalent.]) LIBADD_DL="-lsvld" Index: libltdl/ltdl.c =================================================================== RCS file: /cvsroot/libtool/libtool/libltdl/ltdl.c,v retrieving revision 1.152 diff -u -r1.152 ltdl.c --- libltdl/ltdl.c 2001/08/16 00:48:52 1.152 +++ libltdl/ltdl.c 2001/09/02 17:37:34 @@ -29,6 +29,10 @@ # include #endif +#if HAVE_UNISTD_H +# include +#endif + #if HAVE_STDIO_H # include #endif @@ -113,6 +117,14 @@ /* --- MANIFEST CONSTANTS --- */ +/* Standard libltdl search path environment variable name */ +#undef LTDL_SEARCHPATH_VAR +#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH" + +/* Standard libtool archive file extension. */ +#undef LTDL_ARCHIVE_EXT +#define LTDL_ARCHIVE_EXT ".la" + /* max. filename length */ #ifndef LT_FILENAME_MAX # define LT_FILENAME_MAX 1024 @@ -406,7 +418,7 @@ assert (pargz); assert (pargz_len); assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len)); - + /* If nothing needs to be appended, no more work is required. */ if (buf_len == 0) return 0; @@ -416,7 +428,7 @@ argz = LT_DLREALLOC (char, *pargz, argz_len); if (!argz) return ENOMEM; - + /* Copy characters from BUF after terminating '\0' in ARGZ. */ memcpy (argz + *pargz_len, buf, buf_len); @@ -482,7 +494,7 @@ /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */ if (!argz_len) LT_DLFREE (argz); - + /* Assign new values. */ *pargz = argz; *pargz_len = argz_len; @@ -548,8 +560,8 @@ *pargz = argz; *pargz_len = argz_len; } - - return 0; + + return 0; } #endif /* !HAVE_ARGZ_INSERT */ @@ -693,6 +705,7 @@ #define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)] static const char objdir[] = LTDL_OBJDIR; +static const char archive_ext[] = LTDL_ARCHIVE_EXT; #ifdef LTDL_SHLIB_EXT static const char shlib_ext[] = LTDL_SHLIB_EXT; #endif @@ -706,9 +719,9 @@ /* --- MUTEX LOCKING --- */ -/* Macros to make it easier to run the lock functions only if they have +/* 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 + 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 LT_DLMUTEX_LOCK() LT_STMT_START { \ @@ -752,7 +765,7 @@ /* Lock using the old lock() callback, if any. */ LT_DLMUTEX_LOCK (); - if ((lock && unlock && seterror && geterror) + if ((lock && unlock && seterror && geterror) || !(lock || unlock || seterror || geterror)) { lt_dlmutex_lock_func = lock; @@ -1052,9 +1065,9 @@ { static shl_t self = (shl_t) 0; lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L); - + /* Since searching for a symbol against a NULL module handle will also - look in everything else that was already loaded and exported with + look in everything else that was already loaded and exported with the -E compiler flag, we always cache a handle saved before any modules are loaded. */ if (!self) @@ -1062,7 +1075,7 @@ lt_ptr address; shl_findsym (&self, "main", TYPE_UNDEFINED, &address); } - + if (!filename) { module = self; @@ -1076,7 +1089,7 @@ LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); } } - + return module; } @@ -1116,7 +1129,7 @@ LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); } } - + return address; } @@ -1516,7 +1529,7 @@ { ++errors; } - + done: LT_DLMUTEX_UNLOCK (); return errors; @@ -1657,6 +1670,8 @@ char *deplibs)); static int trim LT_PARAMS((char **dest, const char *str)); +static int try_dlopen LT_PARAMS((lt_dlhandle *handle, + const char *filename)); static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle, const char *filename)); static int unload_deplibs LT_PARAMS((lt_dlhandle handle)); @@ -1737,7 +1752,7 @@ else { presym_free_symlists(); - + LT_DLMUTEX_LOCK (); if (default_preloaded_symbols) { @@ -1909,7 +1924,7 @@ cur->loader = loader; LT_DLMUTEX_SETERROR (saved_error); - + done: LT_DLMUTEX_UNLOCK (); @@ -1936,7 +1951,7 @@ should make it into this function: */ assert (strchr (dirname, LT_DIRSEP_CHAR) == 0); #endif - + if (dirname[dirname_len -1] == '/') --dirname_len; filename_len = dirname_len + 1 + LT_STRLEN (dlname); @@ -1960,7 +1975,7 @@ { ++error; } - + LT_DLFREE (filename); return error; } @@ -2016,7 +2031,7 @@ char **pcanonical; { char *canonical = 0; - + assert (path && *path); assert (pcanonical); @@ -2080,7 +2095,7 @@ size_t *pargz_len; { error_t error; - + assert (path); assert (pargz); assert (pargz_len); @@ -2159,7 +2174,7 @@ filename[lendir++] = '/'; strcpy (filename +lendir, base_name); } - + if ((result = (*func) (filename, data1, data2))) { break; @@ -2173,7 +2188,7 @@ LT_DLFREE (filename); LT_DLMUTEX_UNLOCK (); - + return result; } @@ -2229,22 +2244,31 @@ lt_ptr ignored; { lt_dlhandle *handle = (lt_dlhandle *) data; - int is_done = 0; + int found = access (filename, R_OK); - if (tryall_dlopen (handle, filename) == 0) - { - is_done = 1; - } + /* Bail out if file cannot be read... */ + if (!found) + return 0; - return is_done; + /* Try to dlopen the file, but do not continue searching in any + case. */ + if (tryall_dlopen (handle, filename) != 0) + *handle = 0; + + return 1; } +/* If HANDLE was found return it, otherwise return 0. If HANDLE was + found but could not be opened, *HANDLE will be set to 0. */ static lt_dlhandle * find_handle (search_path, base_name, handle) const char *search_path; const char *base_name; lt_dlhandle *handle; { + if (!search_path) + return 0; + if (!foreach_dirinpath (search_path, base_name, find_handle_callback, handle, 0)) return 0; @@ -2481,45 +2505,57 @@ return 0; } -lt_dlhandle -lt_dlopen (filename) +int +try_dlopen (phandle, filename) + lt_dlhandle *phandle; const char *filename; { - lt_dlhandle handle = 0, newhandle; - const char *ext; - const char *saved_error; - char *canonical = 0, *base_name = 0, *dir = 0, *name = 0; + const char * ext = 0; + const char * saved_error = 0; + char * canonical = 0; + char * base_name = 0; + char * dir = 0; + char * name = 0; + int errors = 0; + lt_dlhandle newhandle; - /* Doing this immediately allows internal functions to safely - assume only canonicalized paths are passed. */ - if (filename && (canonicalize_path (filename, &canonical) != 0)) - return 0; + assert (phandle); + assert (*phandle == 0); LT_DLMUTEX_GETERROR (saved_error); /* dlopen self? */ if (!filename) { - handle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); - if (!handle) - return 0; + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == 0) + return 1; - memset (handle, 0, 1*sizeof(struct lt_dlhandle_struct)); - newhandle = handle; + memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); + newhandle = *phandle; /* lt_dlclose()ing yourself is very bad! Disallow it. */ - LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG); + LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG); if (tryall_dlopen (&newhandle, 0) != 0) { - LT_DLFREE (handle); - return 0; + LT_DLFREE (*phandle); + return 1; } + goto register_handle; } assert (filename && *filename); + /* Doing this immediately allows internal functions to safely + assume only canonicalized paths are passed. */ + if (canonicalize_path (filename, &canonical) != 0) + { + ++errors; + goto cleanup; + } + /* If the canonical module name is a path (relative or absolute) then split it into a directory part and a name part. */ base_name = strrchr (canonical, '/'); @@ -2529,7 +2565,10 @@ dir = LT_EMALLOC (char, 1+ dirlen); if (!dir) - goto cleanup; + { + ++errors; + goto cleanup; + } strncpy (dir, canonical, dirlen); dir[dirlen] = LT_EOS_CHAR; @@ -2538,21 +2577,22 @@ } else LT_DLMEM_REASSIGN (base_name, canonical); - + assert (base_name && *base_name); /* Check whether we are opening a libtool module (.la extension). */ - ext = strrchr(base_name, '.'); - if (ext && strcmp(ext, ".la") == 0) + ext = strrchr (base_name, '.'); + if (ext && strcmp (ext, archive_ext) == 0) { /* this seems to be a libtool module */ - FILE *file = 0; - int i; - char *dlname = 0, *old_name = 0; - char *libdir = 0, *deplibs = 0; - char *line; + FILE * file = 0; + char * dlname = 0; + char * old_name = 0; + char * libdir = 0; + char * deplibs = 0; + char * line = 0; size_t line_len; - int error = 0; + int i; /* if we can't find the installed flag, it is probably an installed libtool archive, produced with an old version @@ -2562,7 +2602,10 @@ /* extract the module name from the file name */ name = LT_EMALLOC (char, ext - base_name + 1); if (!name) - goto cleanup; + { + ++errors; + goto cleanup; + } /* canonicalize the module name */ for (i = 0; i < ext - base_name; ++i) @@ -2576,7 +2619,6 @@ name[i] = '_'; } } - name[ext - base_name] = LT_EOS_CHAR; /* Now try to open the .la file. If there is no directory name @@ -2585,20 +2627,31 @@ yet found) try opening just the module name as passed. */ if (!dir) { - file = find_file (user_search_path, base_name, &dir); + const char *search_path; + + LT_DLMUTEX_LOCK (); + search_path = user_search_path; + if (search_path) + file = find_file (user_search_path, base_name, &dir); + LT_DLMUTEX_UNLOCK (); + if (!file) { - file = find_file (getenv("LTDL_LIBRARY_PATH"), base_name, &dir); + search_path = getenv (LTDL_SEARCHPATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); } #ifdef LTDL_SHLIBPATH_VAR if (!file) { - file = find_file (getenv(LTDL_SHLIBPATH_VAR), base_name, &dir); + search_path = getenv (LTDL_SHLIBPATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); } #endif #ifdef LTDL_SYSSEARCHPATH - if (!file) + if (!file && sys_search_path) { file = find_file (sys_search_path, base_name, &dir); } @@ -2608,32 +2661,34 @@ { file = fopen (filename, LT_READTEXT_MODE); } + + /* If we didn't find the file by now, it really isn't there. Set + the status flag, and bail out. */ if (!file) { LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + ++errors; + goto cleanup; } - if (!file) - goto cleanup; - line_len = LT_FILENAME_MAX; line = LT_EMALLOC (char, line_len); if (!line) { fclose (file); + ++errors; goto cleanup; } /* read the .la file */ - while (!feof(file)) + while (!feof (file)) { if (!fgets (line, line_len, file)) { break; } - - /* Handle the case where we occasionally need to read a line + /* Handle the case where we occasionally need to read a line that is longer than the initial buffer size. */ while (line[LT_STRLEN(line) -1] != '\n') { @@ -2654,7 +2709,7 @@ #define STR_DLNAME "dlname=" if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0) { - error = trim (&dlname, &line[sizeof (STR_DLNAME) - 1]); + errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]); } #undef STR_OLD_LIBRARY @@ -2662,13 +2717,13 @@ else if (strncmp (line, STR_OLD_LIBRARY, sizeof (STR_OLD_LIBRARY) - 1) == 0) { - error = trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); + errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); } #undef STR_LIBDIR #define STR_LIBDIR "libdir=" else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) { - error = trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]); + errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]); } #undef STR_DL_DEPLIBS @@ -2676,7 +2731,7 @@ else if (strncmp (line, STR_DL_DEPLIBS, sizeof (STR_DL_DEPLIBS) - 1) == 0) { - error = trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); + errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); } else if (strcmp (line, "installed=yes\n") == 0) { @@ -2693,21 +2748,22 @@ sizeof (STR_LIBRARY_NAMES) - 1) == 0) { char *last_libname; - error = trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); - if (! error && dlname && - (last_libname = strrchr (dlname, ' ')) != 0) + errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); + if (!errors + && dlname + && (last_libname = strrchr (dlname, ' ')) != 0) { last_libname = lt_estrdup (last_libname + 1); if (!last_libname) { - ++error; + ++errors; goto cleanup; } LT_DLMEM_REASSIGN (dlname, last_libname); } } - if (error) + if (errors) break; } @@ -2715,63 +2771,66 @@ LT_DLFREE (line); /* allocate the handle */ - handle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); - if (!handle) - ++error; + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == 0) + ++errors; - if (error) + if (errors) { free_vars (dlname, old_name, libdir, deplibs); - LT_DLFREE (handle); + LT_DLFREE (*phandle); goto cleanup; } - assert (handle); + assert (*phandle); - memset (handle, 0, sizeof(struct lt_dlhandle_struct)); - if (load_deplibs (handle, deplibs) == 0) + memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); + if (load_deplibs (*phandle, deplibs) == 0) { - newhandle = handle; + newhandle = *phandle; /* find_module may replace newhandle */ if (find_module (&newhandle, dir, libdir, dlname, old_name, installed)) { - unload_deplibs (handle); - error = 1; + unload_deplibs (*phandle); + ++errors; } } else { - error = 1; + ++errors; } free_vars (dlname, old_name, libdir, deplibs); - if (error) + if (errors) { - LT_DLFREE (handle); + LT_DLFREE (*phandle); goto cleanup; } - if (handle != newhandle) + if (*phandle != newhandle) { - unload_deplibs (handle); + unload_deplibs (*phandle); } } else { /* not a libtool module */ - handle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); - if (!handle) - goto cleanup; + *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + if (*phandle == 0) + { + ++errors; + goto cleanup; + } - memset (handle, 0, sizeof(struct lt_dlhandle_struct)); - newhandle = handle; + memset (*phandle, 0, sizeof (struct lt_dlhandle_struct)); + newhandle = *phandle; /* If the module has no directory name component, try to find it 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_handle (user_search_path, base_name, &newhandle) - && !find_handle (getenv ("LTDL_LIBRARY_PATH"), base_name, + && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name, &newhandle) #ifdef LTDL_SHLIBPATH_VAR && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name, @@ -2780,24 +2839,30 @@ #ifdef LTDL_SYSSEARCHPATH && !find_handle (sys_search_path, base_name, &newhandle) #endif - )) && tryall_dlopen (&newhandle, filename)) + ))) + { + tryall_dlopen (&newhandle, filename); + } + + if (!newhandle) { - LT_DLFREE (handle); + LT_DLFREE (*phandle); + ++errors; goto cleanup; } } register_handle: - LT_DLMEM_REASSIGN (handle, newhandle); + LT_DLMEM_REASSIGN (*phandle, newhandle); - if (handle->info.ref_count == 0) + if ((*phandle)->info.ref_count == 0) { - handle->info.ref_count = 1; - LT_DLMEM_REASSIGN (handle->info.name, name); + (*phandle)->info.ref_count = 1; + LT_DLMEM_REASSIGN ((*phandle)->info.name, name); LT_DLMUTEX_LOCK (); - handle->next = handles; - handles = handle; + (*phandle)->next = handles; + handles = *phandle; LT_DLMUTEX_UNLOCK (); } @@ -2808,50 +2873,96 @@ LT_DLFREE (name); LT_DLFREE (canonical); + return errors; +} + +lt_dlhandle +lt_dlopen (filename) + const char *filename; +{ + lt_dlhandle handle = 0; + + /* Just incase we missed a code path in try_dlopen() that reports + an error, but forgets to reset handle... */ + if (try_dlopen (&handle, filename) != 0) + return 0; + return handle; } +/* If the last error messge store was `FILE_NOT_FOUND', then return + non-zero. */ +int +file_not_found () +{ + const char *error = 0; + + LT_DLMUTEX_GETERROR (error); + if (error == LT_DLSTRERROR (FILE_NOT_FOUND)) + return 1; + + return 0; +} + +/* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to + open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT, + and if a file is still not found try again with SHLIB_EXT appended + instead. */ lt_dlhandle lt_dlopenext (filename) const char *filename; { - lt_dlhandle handle; - char *tmp; - int len; - const char *saved_error; - - LT_DLMUTEX_GETERROR (saved_error); + lt_dlhandle handle = 0; + char * tmp = 0; + char * ext = 0; + int len; + int errors = 0; + int file_found = 1; /* until proven otherwise */ if (!filename) { return lt_dlopen (filename); } + assert (filename); + len = LT_STRLEN (filename); - if (!len) + ext = strrchr (filename, '.'); + + /* If FILENAME already bears a suitable extension, there is no need + to try appending additional extensions. */ + if (ext && ((strcmp (ext, archive_ext) == 0) +#ifdef LTDL_SHLIB_EXT + || (strcmp (ext, shlib_ext) == 0) +#endif + )) { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); - return 0; + return lt_dlopen (filename); } - /* try "filename.la" */ - tmp = LT_EMALLOC (char, len+4); + /* First try appending ARCHIVE_EXT. */ + tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1); if (!tmp) return 0; strcpy (tmp, filename); - strcat (tmp, ".la"); - handle = lt_dlopen (tmp); - if (handle) + strcat (tmp, archive_ext); + errors = try_dlopen (&handle, tmp); + + /* If we found FILENAME, stop searching -- whether we were able to + load the file as a module or not. If the file exists but loading + failed, it is better to return an error message here than to + report FILE_NOT_FOUND when the alternatives (foo.so etc) are not + in the module search path. */ + if (handle || ((errors > 0) && file_not_found ())) { - LT_DLMUTEX_SETERROR (saved_error); LT_DLFREE (tmp); return handle; } #ifdef LTDL_SHLIB_EXT - /* try "filename.EXT" */ - if (LT_STRLEN(shlib_ext) > 3) + /* Try appending SHLIB_EXT. */ + if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext)) { LT_DLFREE (tmp); tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1); @@ -2866,22 +2977,19 @@ } strcat(tmp, shlib_ext); - handle = lt_dlopen (tmp); - if (handle) + errors = try_dlopen (&handle, tmp); + + /* As before, if the file was found but loading failed, return now + with the current error message. */ + if (handle || ((errors > 0) && file_not_found ())) { - LT_DLMUTEX_SETERROR (saved_error); LT_DLFREE (tmp); return handle; } #endif - - /* try the normal file name */ - handle = lt_dlopen (filename); - if (handle) - { - return handle; - } + /* Still here? Then we really did fail to locate any of the file + names we tried. */ LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); LT_DLFREE (tmp); return 0; @@ -2987,7 +3095,7 @@ buf = LT_EMALLOC (char, 1+ buf_len); if (!buf) return ++errors; - + assert (buf); strcpy (buf, dirnam); @@ -3001,7 +3109,7 @@ LT_DLFREE (buf); - return errors; + return errors; } int @@ -3012,7 +3120,7 @@ { DIR *dirp = 0; int errors = 0; - + assert (dirnam && *dirnam); assert (pargz); assert (pargz_len); @@ -3356,7 +3464,7 @@ ++errors; goto cleanup; } - + argz_stringify (argz, argz_len, LT_PATHSEP_CHAR); LT_DLMEM_REASSIGN (*ppath, argz); @@ -3366,7 +3474,7 @@ return errors; } - + int lt_dladdsearchdir (search_dir) const char *search_dir; @@ -3394,7 +3502,7 @@ if (before) { LT_DLMUTEX_LOCK (); - if ((before < user_search_path) + if ((before < user_search_path) || (before >= user_search_path + LT_STRLEN (user_search_path))) { LT_DLMUTEX_UNLOCK (); @@ -3407,7 +3515,7 @@ if (search_dir && *search_dir) { LT_DLMUTEX_LOCK (); - if (lt_dlpath_insertdir (&user_search_path, + if (lt_dlpath_insertdir (&user_search_path, (char *) before, search_dir) != 0) { ++errors;