From e2d88014acc7973f8fc1f096488aec6d59ddb263 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 1 Sep 2011 08:17:07 +0000 Subject: [PATCH] * 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. --- winsup/cygwin/ChangeLog | 7 ++++++ winsup/cygwin/dlfcn.cc | 52 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 6f7fcae0b..e9c3ad05e 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,10 @@ +2011-09-01 Corinna Vinschen + + * 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 * flock.cc (inode_t::unlock_and_remove_if_unused): Rename from diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc index fbcdfedfb..067b6001c 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;