Skip to content

Commit

Permalink
os: add os.ModeSocket support to os.Stat on windows
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
qmuntal committed Feb 12, 2024
1 parent 4a7f3ac commit 628b101
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 17 deletions.
3 changes: 3 additions & 0 deletions src/internal/syscall/windows/reparse_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down
20 changes: 20 additions & 0 deletions src/net/unixsock_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
39 changes: 22 additions & 17 deletions src/os/types_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 628b101

Please sign in to comment.