diff --git a/src/internal/syscall/windows/reparse_windows.go b/src/internal/syscall/windows/reparse_windows.go index 02f32c6752592..241dd523c5411 100644 --- a/src/internal/syscall/windows/reparse_windows.go +++ b/src/internal/syscall/windows/reparse_windows.go @@ -9,10 +9,13 @@ import ( "unsafe" ) +// Reparse tag values are taken from +// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/c8e77b37-3909-4fe6-a4ea-2b9d423b1ee4 const ( FSCTL_SET_REPARSE_POINT = 0x000900A4 IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003 IO_REPARSE_TAG_DEDUP = 0x80000013 + IO_REPARSE_TAG_AF_UNIX = 0x80000023 SYMLINK_FLAG_RELATIVE = 1 ) diff --git a/src/net/unixsock_windows_test.go b/src/net/unixsock_windows_test.go index d541d89f78c1e..b3e2260d587b0 100644 --- a/src/net/unixsock_windows_test.go +++ b/src/net/unixsock_windows_test.go @@ -95,3 +95,23 @@ func TestUnixConnLocalWindows(t *testing.T) { } } } + +func TestModeSocket(t *testing.T) { + addr := testUnixAddr(t) + + l, err := Listen("unix", addr) + if err != nil { + t.Fatal(err) + } + defer l.Close() + + stat, err := os.Stat(addr) + if err != nil { + t.Fatal(err) + } + + mode := stat.Mode() + if mode&os.ModeSocket == 0 { + t.Fatalf("%v should have ModeSocket", mode) + } +} diff --git a/src/os/types_windows.go b/src/os/types_windows.go index 6b9fef6c123f6..73433556968d9 100644 --- a/src/os/types_windows.go +++ b/src/os/types_windows.go @@ -184,23 +184,28 @@ func (fs *fileStat) Mode() (m FileMode) { case syscall.FILE_TYPE_CHAR: m |= ModeDevice | ModeCharDevice } - if fs.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 && m&ModeType == 0 { - if fs.ReparseTag == windows.IO_REPARSE_TAG_DEDUP { - // If the Data Deduplication service is enabled on Windows Server, its - // Optimization job may convert regular files to IO_REPARSE_TAG_DEDUP - // whenever that job runs. - // - // However, DEDUP reparse points remain similar in most respects to - // regular files: they continue to support random-access reads and writes - // of persistent data, and they shouldn't add unexpected latency or - // unavailability in the way that a network filesystem might. - // - // Go programs may use ModeIrregular to filter out unusual files (such as - // raw device files on Linux, POSIX FIFO special files, and so on), so - // to avoid files changing unpredictably from regular to irregular we will - // consider DEDUP files to be close enough to regular to treat as such. - } else { - m |= ModeIrregular + if fs.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 { + if fs.ReparseTag == windows.IO_REPARSE_TAG_AF_UNIX { + m |= ModeSocket + } + if m&ModeType == 0 { + if fs.ReparseTag == windows.IO_REPARSE_TAG_DEDUP { + // If the Data Deduplication service is enabled on Windows Server, its + // Optimization job may convert regular files to IO_REPARSE_TAG_DEDUP + // whenever that job runs. + // + // However, DEDUP reparse points remain similar in most respects to + // regular files: they continue to support random-access reads and writes + // of persistent data, and they shouldn't add unexpected latency or + // unavailability in the way that a network filesystem might. + // + // Go programs may use ModeIrregular to filter out unusual files (such as + // raw device files on Linux, POSIX FIFO special files, and so on), so + // to avoid files changing unpredictably from regular to irregular we will + // consider DEDUP files to be close enough to regular to treat as such. + } else { + m |= ModeIrregular + } } } return m