]> Cypherpunks repositories - gostls13.git/commitdiff
os: add os.ModeSocket support to os.Stat on windows
authorqmuntal <quimmuntal@gmail.com>
Wed, 7 Feb 2024 16:40:24 +0000 (17:40 +0100)
committerQuim Muntal <quimmuntal@gmail.com>
Mon, 12 Feb 2024 07:15:06 +0000 (07:15 +0000)
Unix sockets are identified by the IO_REPARSE_TAG_AF_UNIX reparse tag.

Teach fileStat.Mode() to recognize this tag and set the os.ModeSocket
bit in such case.

Note that there is a bug starting in Windows 19H1 until 20H1 that
makes the IO_REPARSE_TAG_AF_UNIX tag not being set for unix sockets.
This CL doesn't provide a workaround for this bug.

Fixes #33357.

Change-Id: Iea8f24b20672c8d4b03f55ef298d128431dc3fac
Reviewed-on: https://go-review.googlesource.com/c/go/+/561937
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
src/internal/syscall/windows/reparse_windows.go
src/net/unixsock_windows_test.go
src/os/types_windows.go

index 02f32c6752592f0d265724d12f8c8878d9281dd2..241dd523c54110c7107ba05df36135c1a46b9a2f 100644 (file)
@@ -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
 )
index d541d89f78c1e875dca9c1b90578aeca985968e6..b3e2260d587b01f1b5ff9b4a7e8b8c7b93c29550 100644 (file)
@@ -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)
+       }
+}
index 6b9fef6c123f61e125c6200a60b0a59f9a498fc6..73433556968d92b178dfb2e9a3b5f9aff0d7c9fc 100644 (file)
@@ -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