mirror of
https://github.com/golang/go
synced 2024-11-23 00:40:08 -07:00
os: add os.ModeSocket support to os.Stat on windows
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>
This commit is contained in:
parent
4a7f3ac8eb
commit
628b1015b9
@ -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
|
||||
)
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user