aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2011-09-01 08:17:07 +0000
committerCorinna Vinschen <corinna@vinschen.de>2011-09-01 08:17:07 +0000
commite2d88014acc7973f8fc1f096488aec6d59ddb263 (patch)
treeb9c96c1e590890d94c539b0abb19660f39ca6049
parent52a5f8cc1a6d3312073b715410253dc219132345 (diff)
downloadnewlib-e2d88014acc7973f8fc1f096488aec6d59ddb263.zip
newlib-e2d88014acc7973f8fc1f096488aec6d59ddb263.tar.gz
newlib-e2d88014acc7973f8fc1f096488aec6d59ddb263.tar.bz2
* dlfcn.cc (gfpod_helper): Helper function to search DLL using
a given DLL name. Change default search path to allow /usr/bin. (get_full_path_of_dll): Find DLLs even if the caller used a ".so" suffix or a "lib" prefix for the DLL.
-rw-r--r--winsup/cygwin/ChangeLog7
-rw-r--r--winsup/cygwin/dlfcn.cc52
2 files changed, 53 insertions, 6 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 6f7fcae..e9c3ad0 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,10 @@
+2011-09-01 Corinna Vinschen <corinna@vinschen.de>
+
+ * dlfcn.cc (gfpod_helper): Helper function to search DLL using
+ a given DLL name. Change default search path to allow /usr/bin.
+ (get_full_path_of_dll): Find DLLs even if the caller used a ".so"
+ suffix or a "lib" prefix for the DLL.
+
2011-08-31 Corinna Vinschen <corinna@vinschen.de>
* flock.cc (inode_t::unlock_and_remove_if_unused): Rename from
diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc
index fbcdfed..067b600 100644
--- a/winsup/cygwin/dlfcn.cc
+++ b/winsup/cygwin/dlfcn.cc
@@ -36,8 +36,20 @@ check_path_access (const char *mywinenv, const char *name, path_conv& buf)
return find_exec (name, buf, mywinenv, FE_NNF | FE_NATIVE | FE_CWD | FE_DLL);
}
-/* Search LD_LIBRARY_PATH for dll, if it exists.
- Return Windows version of given path. */
+/* Search LD_LIBRARY_PATH for dll, if it exists. Search /usr/bin and /usr/lib
+ by default. Return valid full path in path_conv real_filename. */
+static inline bool
+gfpod_helper (const char *name, path_conv &real_filename)
+{
+ if (isabspath (name))
+ real_filename.check (name, PC_SYM_FOLLOW | PC_NULLEMPTY);
+ else if (!check_path_access ("LD_LIBRARY_PATH=", name, real_filename))
+ check_path_access ("/usr/bin:/usr/lib", name, real_filename);
+ if (!real_filename.exists ())
+ real_filename.error = ENOENT;
+ return !real_filename.error;
+}
+
static bool __stdcall
get_full_path_of_dll (const char* str, path_conv &real_filename)
{
@@ -55,11 +67,39 @@ get_full_path_of_dll (const char* str, path_conv &real_filename)
strcpy (name, str); /* Put it somewhere where we can manipulate it. */
- if (isabspath (name) ||
- (check_path_access ("LD_LIBRARY_PATH=", name, real_filename)
- ?: check_path_access ("/usr/lib", name, real_filename)) == NULL)
- real_filename.check (name, PC_SYM_FOLLOW | PC_NOFULL | PC_NULLEMPTY);
+ char *basename = strrchr (name, '/');
+ basename = basename ? basename + 1 : name;
+ char *suffix = strrchr (name, '.');
+ if (suffix && suffix < basename)
+ suffix = NULL;
+
+ /* Is suffix ".so"? */
+ if (suffix && !strcmp (suffix, ".so"))
+ {
+ /* Does the file exist? */
+ if (gfpod_helper (name, real_filename))
+ return true;
+ /* No, replace ".so" with ".dll". */
+ strcpy (suffix, ".dll");
+ }
+ /* Does the filename start with "lib"? */
+ if (!strncmp (basename, "lib", 3))
+ {
+ /* Yes, replace "lib" with "cyg". */
+ strncpy (basename, "cyg", 3);
+ /* Does the file exist? */
+ if (gfpod_helper (name, real_filename))
+ return true;
+ /* No, revert back to "lib". */
+ strncpy (basename, "lib", 3);
+ }
+ if (gfpod_helper (name, real_filename))
+ return true;
+ /* If nothing worked, create a relative path from the original incoming
+ filename and let LoadLibrary search for it using the system default
+ DLL search path. */
+ real_filename.check (str, PC_SYM_FOLLOW | PC_NOFULL | PC_NULLEMPTY);
if (!real_filename.error)
return true;