[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:54 PDT 2026
================
@@ -161,33 +167,63 @@ inline int stat_handle(HANDLE h, StatT* buf) {
} else {
buf->st_mode |= _S_IFREG;
}
+ bool is_af_unix_socket = false;
if (basic.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
FILE_ATTRIBUTE_TAG_INFO tag;
if (!GetFileInformationByHandleEx(h, FileAttributeTagInfo, &tag, sizeof(tag)))
return -1;
- if (tag.ReparseTag == IO_REPARSE_TAG_SYMLINK)
+ if (tag.ReparseTag == IO_REPARSE_TAG_SYMLINK) {
buf->st_mode = (buf->st_mode & ~_S_IFMT) | _S_IFLNK;
+ } else if (tag.ReparseTag == IO_REPARSE_TAG_AF_UNIX) {
+ buf->st_mode = (buf->st_mode & ~_S_IFMT) | _S_IFSOCK;
+ is_af_unix_socket = true;
+ }
}
FILE_STANDARD_INFO standard;
- if (!GetFileInformationByHandleEx(h, FileStandardInfo, &standard, sizeof(standard)))
+ if (!GetFileInformationByHandleEx(h, FileStandardInfo, &standard, sizeof(standard))) {
+ // AF_UNIX (Unix domain) socket files don't support all of the information
+ // queries below; report what we already have (mode/timestamps) instead of
+ // failing outright, matching the behavior of the system stat()/os.stat().
+ if (is_af_unix_socket)
+ return 0;
return -1;
+ }
buf->st_nlink = standard.NumberOfLinks;
buf->st_size = standard.EndOfFile.QuadPart;
BY_HANDLE_FILE_INFORMATION info;
- if (!GetFileInformationByHandle(h, &info))
+ if (!GetFileInformationByHandle(h, &info)) {
+ if (is_af_unix_socket)
+ return 0;
return -1;
+ }
buf->st_dev = info.dwVolumeSerialNumber;
memcpy(&buf->st_ino.id[0], &info.nFileIndexHigh, 4);
memcpy(&buf->st_ino.id[4], &info.nFileIndexLow, 4);
return 0;
}
inline int stat_file(const wchar_t* path, StatT* buf, DWORD flags) {
- WinHandle h(path, FILE_READ_ATTRIBUTES, flags);
- if (!h)
- return -1;
- int ret = stat_handle(h, buf);
- return ret;
+ {
+ WinHandle h(path, FILE_READ_ATTRIBUTES, flags);
+ if (h && stat_handle(h, buf) == 0)
+ return 0;
+ }
+ // Some reparse points, such as AF_UNIX (Unix domain) socket files, can't be
+ // opened/queried by following the reparse point (there is no target to
+ // follow). CreateFileW may fail with e.g. ERROR_CANT_ACCESS_FILE, or the
+ // subsequent GetFileInformationByHandle* calls may fail. In that case, fall
+ // back to opening the reparse point itself so that we can still report its
+ // attributes and type. This matches the behavior of the system
+ // stat()/os.stat() on such files.
+ if (!(flags & FILE_FLAG_OPEN_REPARSE_POINT)) {
+ DWORD attributes = GetFileAttributesW(path);
----------------
georgthegreat wrote:
I will deslop this in a while
https://github.com/llvm/llvm-project/pull/213233
More information about the libcxx-commits
mailing list