[libcxx-commits] [libcxx] Properly implement std::fs::is_socket() on Windows (PR #213233)

Yuriy Chernyshov via libcxx-commits libcxx-commits at lists.llvm.org
Fri Aug 7 01:20:53 PDT 2026


================
@@ -182,17 +196,38 @@ inline int stat_handle(HANDLE h, StatT* buf) {
   return 0;
 }
 
-inline int stat_file(const wchar_t* path, StatT* buf, DWORD flags) {
-  WinHandle h(path, FILE_READ_ATTRIBUTES, flags);
-  if (!h)
+inline int stat_file(const wchar_t* path, StatT* buf, bool follow_symlinks) {
+  // Win32 has no open mode that means "follow symlinks, but open any other
+  // reparse point (e.g. an AF_UNIX socket) as itself": omitting
+  // FILE_FLAG_OPEN_REPARSE_POINT follows *every* reparse point, which fails for
+  // ones that have no target to follow, while passing it opens *every* reparse
+  // point as itself, including symlinks we do want to follow.
+  //
+  // So we always open the reparse point itself first. This succeeds for any
+  // existing object regardless of its reparse tag, and lets stat_handle
+  // determine the type from that tag. We then emulate symlink following
+  // ourselves below, only for the objects that actually are symlinks.
+  WinHandle h(path, FILE_READ_ATTRIBUTES, FILE_FLAG_OPEN_REPARSE_POINT);
+  if (!h || stat_handle(h, buf) != 0)
----------------
georgthegreat wrote:

This is a notable change and a slight theoretical performance degradation.
Windows can not distinct between «open reparse points» and «follow reparse points» behaviour, hence I have chosen to do a no-follow version first and then follow if it is what caller requested

https://github.com/llvm/llvm-project/pull/213233


More information about the libcxx-commits mailing list