summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Núñez <ianmalcom@gmail.com>2017-10-02 09:42:07 (GMT)
committerBrad King <brad.king@kitware.com>2017-10-24 15:04:23 (GMT)
commit640709e7db054e90d5e6609eeb16a01af34b5a5a (patch)
tree84b5f1f1c56d3139a00790a4bd9dde2dd6f5ee92
parentd41582fc94e823cbfbb214e08e73ad214619a71a (diff)
downloadCMake-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
-rw-r--r--Source/cmSystemTools.cxx35
-rw-r--r--Source/cmSystemTools.h4
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;