diff options
author | Manuel Núñez <ianmalcom@gmail.com> | 2017-10-02 09:42:07 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2017-10-24 15:04:23 (GMT) |
commit | 640709e7db054e90d5e6609eeb16a01af34b5a5a (patch) | |
tree | 84b5f1f1c56d3139a00790a4bd9dde2dd6f5ee92 /Source | |
parent | d41582fc94e823cbfbb214e08e73ad214619a71a (diff) | |
download | CMake-640709e7db054e90d5e6609eeb16a01af34b5a5a.zip CMake-640709e7db054e90d5e6609eeb16a01af34b5a5a.tar.gz CMake-640709e7db054e90d5e6609eeb16a01af34b5a5a.tar.bz2 |
cmSystemTools: Implement GetRealPath on Windows
Override the KWSys GetRealPath on Windows and use uv_fs_realpath first
to resolve symbolic links.
Fixes: #17206
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmSystemTools.cxx | 35 | ||||
-rw-r--r-- | Source/cmSystemTools.h | 4 |
2 files changed, 39 insertions, 0 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 63c1452..5d1f5f7 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -50,6 +50,8 @@ #include <windows.h> // include wincrypt.h after windows.h #include <wincrypt.h> + +#include "cm_uv.h" #else #include <sys/time.h> #include <unistd.h> @@ -943,6 +945,39 @@ cmSystemTools::WindowsFileRetry cmSystemTools::GetWindowsFileRetry() } return retry; } + +std::string cmSystemTools::GetRealPath(const std::string& path, + std::string* errorMessage) +{ + // uv_fs_realpath uses Windows Vista API so fallback to kwsys if not found + std::string resolved_path; + uv_fs_t req; + int err = uv_fs_realpath(NULL, &req, path.c_str(), NULL); + if (!err) { + resolved_path = std::string((char*)req.ptr); + cmSystemTools::ConvertToUnixSlashes(resolved_path); + // Normalize to upper-case drive letter as GetActualCaseForPath does. + if (resolved_path.size() > 1 && resolved_path[1] == ':') { + resolved_path[0] = toupper(resolved_path[0]); + } + } else if (err == UV_ENOSYS) { + resolved_path = cmsys::SystemTools::GetRealPath(path, errorMessage); + } else if (errorMessage) { + LPSTR message = NULL; + DWORD size = FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&message, 0, + NULL); + *errorMessage = std::string(message, size); + LocalFree(message); + + resolved_path = ""; + } else { + resolved_path = path; + } + return resolved_path; +} #endif bool cmSystemTools::RenameFile(const char* oldname, const char* newname) diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index e7082e6..2646df9 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -497,6 +497,10 @@ public: unsigned int Delay; }; static WindowsFileRetry GetWindowsFileRetry(); + + /** Get the real path for a given path, removing all symlinks. */ + static std::string GetRealPath(const std::string& path, + std::string* errorMessage = 0); #endif private: static bool s_ForceUnixPaths; |