[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