[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
Tue Nov 10 08:38:39 PST 2020


mstorsjo created this revision.
mstorsjo added a reviewer: libc++.
Herald added a project: libc++.
Herald added 1 blocking reviewer(s): libc++.
mstorsjo requested review of this revision.

Also ifdef out the fchmod function and call.


Repository:
  rG LLVM Github Monorepo

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
@@ -593,9 +593,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) {
@@ -667,6 +669,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();
@@ -675,6 +678,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);
@@ -1046,8 +1050,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);
   }
@@ -1332,6 +1338,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)
@@ -1346,6 +1353,31 @@
     return err.report(capture_errno());
   }
 #endif
+#else
+  DWORD attributes = GetFileAttributesW(p.c_str());
+  if (attributes == INVALID_FILE_ATTRIBUTES)
+    return err.report(detail::capture_last_error());
+  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::capture_last_error());
+    FILE_BASIC_INFO basic;
+    if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
+      return err.report(detail::capture_last_error());
+    basic.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
+    if ((static_cast<int>(prms) & 0222) == 0)
+      basic.FileAttributes |= FILE_ATTRIBUTE_READONLY;
+    if (!SetFileInformationByHandle(h, FileBasicInfo, &basic, sizeof(basic)))
+      return err.report(detail::capture_last_error());
+  } else {
+    attributes &= ~FILE_ATTRIBUTE_READONLY;
+    if ((static_cast<int>(prms) & 0222) == 0)
+      attributes |= FILE_ATTRIBUTE_READONLY;
+    if (!SetFileAttributesW(p.c_str(), attributes))
+      return err.report(detail::capture_last_error());
+  }
+#endif
 }
 
 path __read_symlink(const path& p, error_code* ec) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D91171.304207.patch
Type: text/x-patch
Size: 2851 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20201110/d1da1191/attachment-0001.bin>


More information about the libcxx-commits mailing list