summaryrefslogtreecommitdiff
path: root/Source/cmSystemTools.cxx
diff options
context:
space:
mode:
authorSergei Kryvonos <sergeikrivonos@gmail.com>2022-02-22 18:37:30 +0200
committerBrad King <brad.king@kitware.com>2022-03-01 08:48:46 -0500
commit5101d586c4634aa9edbbb14dd43904b1599fae9f (patch)
treed7b1be2c30ffa3b8012d229d3a4743b5995bbd9c /Source/cmSystemTools.cxx
parent82b8bd4ef9dcae162ecbffa5604d590c9d6ed929 (diff)
downloadcmake-5101d586c4634aa9edbbb14dd43904b1599fae9f.tar.gz
Windows: Prefer junctions for directory symlinks
Update the approach added by commit afb7f6e4ff (cmake: Add '-E create_symlink' support on Windows, 2018-06-11, v3.13.0-rc1~75^2) to use junctions, as suggested [here](https://superuser.com/a/1291446/140450). This allows them to work under security limitations on Windows. Fixes: #23257
Diffstat (limited to 'Source/cmSystemTools.cxx')
-rw-r--r--Source/cmSystemTools.cxx14
1 files changed, 12 insertions, 2 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index effb837f15..a5dfa4c676 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -3314,12 +3314,22 @@ cmsys::Status cmSystemTools::CreateSymlink(std::string const& origName,
uv_fs_t req;
int flags = 0;
#if defined(_WIN32)
- if (cmsys::SystemTools::FileIsDirectory(origName)) {
- flags |= UV_FS_SYMLINK_DIR;
+ bool const isDir = cmsys::SystemTools::FileIsDirectory(origName);
+ if (isDir) {
+ flags |= UV_FS_SYMLINK_JUNCTION;
}
#endif
int err = uv_fs_symlink(nullptr, &req, origName.c_str(), newName.c_str(),
flags, nullptr);
+#if defined(_WIN32)
+ if (err && uv_fs_get_system_error(&req) == ERROR_NOT_SUPPORTED && isDir) {
+ // Try fallback to symlink for network (requires additional permissions).
+ flags ^= UV_FS_SYMLINK_JUNCTION | UV_FS_SYMLINK_DIR;
+ err = uv_fs_symlink(nullptr, &req, origName.c_str(), newName.c_str(),
+ flags, nullptr);
+ }
+#endif
+
cmsys::Status status;
if (err) {
#if defined(_WIN32)