From 5101d586c4634aa9edbbb14dd43904b1599fae9f Mon Sep 17 00:00:00 2001 From: Sergei Kryvonos Date: Tue, 22 Feb 2022 18:37:30 +0200 Subject: 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 --- Source/cmSystemTools.cxx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index effb837..a5dfa4c 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) -- cgit v0.12