[libcxx-commits] [PATCH] D91171: [16/N] [libcxx] Implement the permissions function for windows
Martin Storsjö via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Dec 7 04:08:43 PST 2020
mstorsjo updated this revision to Diff 309867.
mstorsjo set the repository for this revision to rG LLVM Github Monorepo.
mstorsjo added a comment.
Added comments about the two conditional branches, skipping the set operation if there's no change.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D91171/new/
https://reviews.llvm.org/D91171
Files:
libcxx/src/filesystem/operations.cpp
Index: libcxx/src/filesystem/operations.cpp
===================================================================
--- libcxx/src/filesystem/operations.cpp
+++ libcxx/src/filesystem/operations.cpp
@@ -672,9 +672,11 @@
return static_cast<perms>(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) {
@@ -746,6 +748,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();
@@ -754,6 +757,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);
@@ -1136,8 +1140,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);
}
@@ -1424,6 +1430,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)
@@ -1438,6 +1445,41 @@
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) {
+ // If the file is a symlink, and we are supposed to operate on the target
+ // of the symlink, we need to open a handle to it, without the
+ // FILE_FLAG_OPEN_REPARSE_POINT flag, to open the destination of the
+ // symlink, and operate on it via the handle.
+ 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()));
+ DWORD orig_attributes = basic.FileAttributes;
+ basic.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
+ if ((static_cast<int>(prms) & 0222) == 0)
+ basic.FileAttributes |= FILE_ATTRIBUTE_READONLY;
+ if (basic.FileAttributes != orig_attributes &&
+ !SetFileInformationByHandle(h, FileBasicInfo, &basic, sizeof(basic)))
+ return err.report(detail::make_windows_error(GetLastError()));
+ } else {
+ // For a non-symlink, or if operating on the symlink itself instead of
+ // its target, we can use SetFileAttributesW, saving a few calls.
+ DWORD orig_attributes = attributes;
+ attributes &= ~FILE_ATTRIBUTE_READONLY;
+ if ((static_cast<int>(prms) & 0222) == 0)
+ attributes |= FILE_ATTRIBUTE_READONLY;
+ if (attributes != orig_attributes &&
+ !SetFileAttributesW(p.c_str(), attributes))
+ return err.report(detail::make_windows_error(GetLastError()));
+ }
+#endif
}
path __read_symlink(const path& p, error_code* ec) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D91171.309867.patch
Type: text/x-patch
Size: 3526 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20201207/9fcdb4d4/attachment.bin>
More information about the libcxx-commits
mailing list