mirror of
https://github.com/gulrak/filesystem.git
synced 2026-07-30 16:26:11 +08:00
Work on handling of relative symlinks on Windows, refs #211
This commit is contained in:
parent
dded74dfb5
commit
f037641e70
@ -2199,7 +2199,7 @@ GHC_INLINE std::unique_ptr<REPARSE_DATA_BUFFER, free_deleter<REPARSE_DATA_BUFFER
|
||||
}
|
||||
#endif
|
||||
|
||||
GHC_INLINE path resolveSymlink(const path& p, std::error_code& ec)
|
||||
GHC_INLINE path resolveSymlink(const path& p, std::error_code& ec, bool resolve_relative)
|
||||
{
|
||||
#ifdef GHC_OS_WINDOWS
|
||||
path result;
|
||||
@ -2217,7 +2217,7 @@ GHC_INLINE path resolveSymlink(const path& p, std::error_code& ec)
|
||||
else {
|
||||
result = substituteName;
|
||||
}
|
||||
if (reparseData->SymbolicLinkReparseBuffer.Flags & 0x1 /*SYMLINK_FLAG_RELATIVE*/) {
|
||||
if (resolve_relative && reparseData->SymbolicLinkReparseBuffer.Flags & 0x1 /*SYMLINK_FLAG_RELATIVE*/) {
|
||||
result = p.parent_path() / result;
|
||||
}
|
||||
break;
|
||||
@ -2233,6 +2233,7 @@ GHC_INLINE path resolveSymlink(const path& p, std::error_code& ec)
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
(void)resolve_relative;
|
||||
size_t bufferSize = 256;
|
||||
while (true) {
|
||||
std::vector<char> buffer(bufferSize, static_cast<char>(0));
|
||||
@ -2250,6 +2251,11 @@ GHC_INLINE path resolveSymlink(const path& p, std::error_code& ec)
|
||||
#endif
|
||||
}
|
||||
|
||||
GHC_INLINE path resolveSymlink(const path& p, std::error_code& ec)
|
||||
{
|
||||
return resolveSymlink(p, ec, true);
|
||||
}
|
||||
|
||||
#ifdef GHC_OS_WINDOWS
|
||||
GHC_INLINE file_time_type timeFromFILETIME(const FILETIME& ft)
|
||||
{
|
||||
@ -4088,16 +4094,18 @@ GHC_INLINE void copy_symlink(const path& existing_symlink, const path& new_symli
|
||||
GHC_INLINE void copy_symlink(const path& existing_symlink, const path& new_symlink, std::error_code& ec) noexcept
|
||||
{
|
||||
ec.clear();
|
||||
auto to = read_symlink(existing_symlink, ec);
|
||||
auto resolved_to = read_symlink(existing_symlink, ec);
|
||||
if (!ec) {
|
||||
#ifdef GHC_OS_WINDOWS
|
||||
auto resolved_to = to.is_absolute() ? to : existing_symlink.parent_path() / to;
|
||||
auto to = detail::resolveSymlink(existing_symlink, ec, false);
|
||||
if (!ec) {
|
||||
auto to_directory = exists(resolved_to, ec) && is_directory(resolved_to, ec);
|
||||
if (!ec) {
|
||||
detail::create_symlink_unchecked(to, new_symlink, to_directory, ec);
|
||||
}
|
||||
}
|
||||
#else
|
||||
create_symlink(to, new_symlink, ec);
|
||||
create_symlink(resolved_to, new_symlink, ec);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1927,19 +1927,31 @@ TEST_CASE("fs.op.copy_symlink - copy_symlink", "[filesystem][operations][fs.op.c
|
||||
|
||||
CHECK_NOTHROW(fs::copy_symlink("links/relative-dir-link", "links/relative-dir-copy"));
|
||||
CHECK(fs::is_directory("links/relative-dir-copy"));
|
||||
#ifdef GHC_OS_WINDOWS
|
||||
CHECK(fs::read_symlink("links/relative-dir-copy") == fs::path("links/dir-target"));
|
||||
#else
|
||||
CHECK(fs::read_symlink("links/relative-dir-copy") == fs::path("dir-target"));
|
||||
#endif
|
||||
|
||||
ec = std::make_error_code(std::errc::invalid_argument);
|
||||
CHECK_NOTHROW(fs::copy_symlink("links/relative-file-link", "links/relative-file-copy", ec));
|
||||
CHECK(!ec);
|
||||
CHECK(fs::is_regular_file("links/relative-file-copy"));
|
||||
#ifdef GHC_OS_WINDOWS
|
||||
CHECK(fs::read_symlink("links/relative-file-copy") == fs::path("links/file-target"));
|
||||
#else
|
||||
CHECK(fs::read_symlink("links/relative-file-copy") == fs::path("file-target"));
|
||||
#endif
|
||||
|
||||
fs::create_symlink("missing-target", "links/dangling-link");
|
||||
CHECK_NOTHROW(fs::copy_symlink("links/dangling-link", "links/dangling-copy", ec));
|
||||
CHECK(!ec);
|
||||
CHECK(fs::is_symlink("links/dangling-copy"));
|
||||
#ifdef GHC_OS_WINDOWS
|
||||
CHECK(fs::read_symlink("links/dangling-copy") == fs::path("links/missing-target"));
|
||||
#else
|
||||
CHECK(fs::read_symlink("links/dangling-copy") == fs::path("missing-target"));
|
||||
#endif
|
||||
|
||||
fs::create_symlink(fs::absolute("foo"), "links/absolute-link");
|
||||
CHECK_NOTHROW(fs::copy_symlink("links/absolute-link", "links/absolute-copy"));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user