diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2011-09-01 08:17:07 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2011-09-01 08:17:07 +0000 |
commit | e2d88014acc7973f8fc1f096488aec6d59ddb263 (patch) | |
tree | b9c96c1e590890d94c539b0abb19660f39ca6049 | |
parent | 52a5f8cc1a6d3312073b715410253dc219132345 (diff) | |
download | newlib-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/ChangeLog | 7 | ||||
-rw-r--r-- | winsup/cygwin/dlfcn.cc | 52 |
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; |