[libcxx] Implement the stat function family on top of native windows APIs

While the windows CRTs (the modern UCRT, and the legacy msvcrt.dll
that mingw still often defaults to) do provide stat functions, they're
a bit lacking - they only provide second precision on the modification
time, lack support for symlinks and a few other details.

Instead reimplement them using a couple windows native functions,
getting exactly the info we need. (Technically, the implementation
within the CRT calls these functions anyway.)

If we only need a few fields, we could also do with fewer calls, as a
later optimization.

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

GitOrigin-RevId: 2ff8662b5d16129ec6d1ee60dcec4f6ff8f717e2
diff --git a/src/filesystem/operations.cpp b/src/filesystem/operations.cpp
index 50a895d..548a027 100644
--- a/src/filesystem/operations.cpp
+++ b/src/filesystem/operations.cpp
@@ -17,6 +17,8 @@
 
 #include "filesystem_common.h"
 
+#include "posix_compat.h"
+
 #if defined(_LIBCPP_WIN32API)
 # define WIN32_LEAN_AND_MEAN
 # define NOMINMAX
@@ -495,7 +497,7 @@
 
 file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) {
   error_code m_ec;
-  if (::stat(p.c_str(), &path_stat) == -1)
+  if (detail::stat(p.c_str(), &path_stat) == -1)
     m_ec = detail::capture_errno();
   return create_file_status(m_ec, p, path_stat, ec);
 }
@@ -507,7 +509,7 @@
 
 file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) {
   error_code m_ec;
-  if (::lstat(p.c_str(), &path_stat) == -1)
+  if (detail::lstat(p.c_str(), &path_stat) == -1)
     m_ec = detail::capture_errno();
   return create_file_status(m_ec, p, path_stat, ec);
 }
@@ -545,7 +547,7 @@
   m_status = file_status{};
   m_stat = {};
   error_code m_ec;
-  if (::fstat(fd, &m_stat) == -1)
+  if (detail::fstat(fd, &m_stat) == -1)
     m_ec = capture_errno();
   m_status = create_file_status(m_ec, name, m_stat, &ec);
   return m_status;
@@ -1197,7 +1199,7 @@
   auto buff = std::unique_ptr<char[], NullDeleter>(stack_buff);
 #else
   StatT sb;
-  if (::lstat(p.c_str(), &sb) == -1) {
+  if (detail::lstat(p.c_str(), &sb) == -1) {
     return err.report(capture_errno());
   }
   const size_t size = sb.st_size + 1;