Index: libcxx/src/filesystem/operations.cpp =================================================================== --- libcxx/src/filesystem/operations.cpp +++ libcxx/src/filesystem/operations.cpp @@ -667,9 +667,11 @@ return static_cast(st.st_mode) & perms::mask; } +#if !defined(_LIBCPP_WIN32API) ::mode_t posix_convert_perms(perms prms) { return static_cast< ::mode_t>(prms & perms::mask); } +#endif file_status create_file_status(error_code& m_ec, path const& p, const StatT& path_stat, error_code* ec) { @@ -741,6 +743,7 @@ return false; } +#if !defined(_LIBCPP_WIN32API) bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) { if (::fchmod(fd.fd, st.st_mode) == -1) { ec = capture_errno(); @@ -749,6 +752,7 @@ ec.clear(); return false; } +#endif bool stat_equivalent(const StatT& st1, const StatT& st2) { return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino); @@ -1120,8 +1124,10 @@ return err.report(errc::bad_file_descriptor); // Set the permissions and truncate the file we opened. +#if !defined(_LIBCPP_WIN32API) if (detail::posix_fchmod(to_fd, from_stat, m_ec)) return err.report(m_ec); +#endif if (detail::posix_ftruncate(to_fd, 0, m_ec)) return err.report(m_ec); } @@ -1406,6 +1412,7 @@ else if (remove_perms) prms = st.permissions() & ~prms; } +#if !defined(_LIBCPP_WIN32API) const auto real_perms = detail::posix_convert_perms(prms); #if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD) @@ -1420,6 +1427,31 @@ return err.report(capture_errno()); } #endif +#else + DWORD attributes = GetFileAttributesW(p.c_str()); + if (attributes == INVALID_FILE_ATTRIBUTES) + return err.report(detail::make_windows_error(GetLastError())); + if (attributes & FILE_ATTRIBUTE_REPARSE_POINT && resolve_symlinks) { + detail::WinHandle h(p.c_str(), FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, + 0); + if (!h) + return err.report(detail::make_windows_error(GetLastError())); + FILE_BASIC_INFO basic; + if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic))) + return err.report(detail::make_windows_error(GetLastError())); + basic.FileAttributes &= ~FILE_ATTRIBUTE_READONLY; + if ((static_cast(prms) & 0222) == 0) + basic.FileAttributes |= FILE_ATTRIBUTE_READONLY; + if (!SetFileInformationByHandle(h, FileBasicInfo, &basic, sizeof(basic))) + return err.report(detail::make_windows_error(GetLastError())); + } else { + attributes &= ~FILE_ATTRIBUTE_READONLY; + if ((static_cast(prms) & 0222) == 0) + attributes |= FILE_ATTRIBUTE_READONLY; + if (!SetFileAttributesW(p.c_str(), attributes)) + return err.report(detail::make_windows_error(GetLastError())); + } +#endif } path __read_symlink(const path& p, error_code* ec) {