diff options
Diffstat (limited to 'Source/cmSystemTools.cxx')
-rw-r--r-- | Source/cmSystemTools.cxx | 35 |
1 files changed, 35 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) |