? 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;