[libcxx] Hook up a number of operation functions to their windows counterparts

Use the corresponding wchar functions, named "_wfunc" instead of "func",
where feasible, or reimplement functions with native windows APIs.

Differential Revision: https://reviews.llvm.org/D91143

GitOrigin-RevId: efec3cc6524bc536459b9cb6faca190b1e3804b6
diff --git a/src/filesystem/operations.cpp b/src/filesystem/operations.cpp
index 40a863d..ddb4d75 100644
--- a/src/filesystem/operations.cpp
+++ b/src/filesystem/operations.cpp
@@ -405,7 +405,7 @@
   static FileDescriptor create(const path* p, error_code& ec, Args... args) {
     ec.clear();
     int fd;
-    if ((fd = ::open(p->c_str(), args...)) == -1) {
+    if ((fd = detail::open(p->c_str(), args...)) == -1) {
       ec = capture_errno();
       return FileDescriptor{p};
     }
@@ -431,7 +431,7 @@
 
   void close() noexcept {
     if (fd != -1)
-      ::close(fd);
+      detail::close(fd);
     fd = -1;
   }
 
@@ -521,7 +521,7 @@
 
 // http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
 bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) {
-  if (::ftruncate(fd.fd, to_size) == -1) {
+  if (detail::ftruncate(fd.fd, to_size) == -1) {
     ec = capture_errno();
     return true;
   }
@@ -828,8 +828,8 @@
   ErrorHandler<bool> err("copy_file", ec, &to, &from);
 
   error_code m_ec;
-  FileDescriptor from_fd =
-      FileDescriptor::create_with_status(&from, m_ec, O_RDONLY | O_NONBLOCK);
+  FileDescriptor from_fd = FileDescriptor::create_with_status(
+      &from, m_ec, O_RDONLY | O_NONBLOCK | O_BINARY);
   if (m_ec)
     return err.report(m_ec);
 
@@ -881,7 +881,7 @@
 
   // Don't truncate right away. We may not be opening the file we originally
   // looked at; we'll check this later.
-  int to_open_flags = O_WRONLY;
+  int to_open_flags = O_WRONLY | O_BINARY;
   if (!to_exists)
     to_open_flags |= O_CREAT;
   FileDescriptor to_fd = FileDescriptor::create_with_status(
@@ -917,10 +917,13 @@
   if (ec && *ec) {
     return;
   }
-  // NOTE: proposal says you should detect if you should call
-  // create_symlink or create_directory_symlink. I don't think this
-  // is needed with POSIX
-  __create_symlink(real_path, new_symlink, ec);
+#if defined(_LIBCPP_WIN32API)
+  error_code local_ec;
+  if (is_directory(real_path, local_ec))
+    __create_directory_symlink(real_path, new_symlink, ec);
+  else
+#endif
+    __create_symlink(real_path, new_symlink, ec);
 }
 
 bool __create_directories(const path& p, error_code* ec) {
@@ -953,7 +956,7 @@
 bool __create_directory(const path& p, error_code* ec) {
   ErrorHandler<bool> err("create_directory", ec, &p);
 
-  if (::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0)
+  if (detail::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0)
     return true;
 
   if (errno == EEXIST) {
@@ -981,7 +984,7 @@
     return err.report(errc::not_a_directory,
                       "the specified attribute path is invalid");
 
-  if (::mkdir(p.c_str(), attr_stat.st_mode) == 0)
+  if (detail::mkdir(p.c_str(), attr_stat.st_mode) == 0)
     return true;
 
   if (errno == EEXIST) {
@@ -1000,19 +1003,19 @@
 void __create_directory_symlink(path const& from, path const& to,
                                 error_code* ec) {
   ErrorHandler<void> err("create_directory_symlink", ec, &from, &to);
-  if (::symlink(from.c_str(), to.c_str()) != 0)
+  if (detail::symlink_dir(from.c_str(), to.c_str()) == -1)
     return err.report(capture_errno());
 }
 
 void __create_hard_link(const path& from, const path& to, error_code* ec) {
   ErrorHandler<void> err("create_hard_link", ec, &from, &to);
-  if (::link(from.c_str(), to.c_str()) == -1)
+  if (detail::link(from.c_str(), to.c_str()) == -1)
     return err.report(capture_errno());
 }
 
 void __create_symlink(path const& from, path const& to, error_code* ec) {
   ErrorHandler<void> err("create_symlink", ec, &from, &to);
-  if (::symlink(from.c_str(), to.c_str()) == -1)
+  if (detail::symlink_file(from.c_str(), to.c_str()) == -1)
     return err.report(capture_errno());
 }
 
@@ -1032,7 +1035,7 @@
 
 void __current_path(const path& p, error_code* ec) {
   ErrorHandler<void> err("current_path", ec, &p);
-  if (::chdir(p.c_str()) == -1)
+  if (detail::chdir(p.c_str()) == -1)
     err.report(capture_errno());
 }
 
@@ -1236,7 +1239,7 @@
 
 bool __remove(const path& p, error_code* ec) {
   ErrorHandler<bool> err("remove", ec, &p);
-  if (::remove(p.c_str()) == -1) {
+  if (detail::remove(p.c_str()) == -1) {
     if (errno != ENOENT)
       err.report(capture_errno());
     return false;
@@ -1285,13 +1288,13 @@
 
 void __rename(const path& from, const path& to, error_code* ec) {
   ErrorHandler<void> err("rename", ec, &from, &to);
-  if (::rename(from.c_str(), to.c_str()) == -1)
+  if (detail::rename(from.c_str(), to.c_str()) == -1)
     err.report(capture_errno());
 }
 
 void __resize_file(const path& p, uintmax_t size, error_code* ec) {
   ErrorHandler<void> err("resize_file", ec, &p);
-  if (::truncate(p.c_str(), static_cast< ::off_t>(size)) == -1)
+  if (detail::truncate(p.c_str(), static_cast< ::off_t>(size)) == -1)
     return err.report(capture_errno());
 }