WSA_FLAG_OVERLAPPED = 0x01
WSA_FLAG_NO_HANDLE_INHERIT = 0x80
- WSAEMSGSIZE syscall.Errno = 10040
+ WSAEINVAL syscall.Errno = 10022
+ WSAEMSGSIZE syscall.Errno = 10040
+ WSAEAFNOSUPPORT syscall.Errno = 10047
MSG_PEEK = 0x2
MSG_TRUNC = 0x0100
import (
"sync"
- _ "unsafe" // for linkname
+ "syscall"
+ "unsafe"
)
// version retrieves the major, minor, and build version numbers
// Unix Domain Sockets.
// The minimal requirement is Windows 10.0.17063.
var SupportUnixSocket = sync.OnceValue(func() bool {
- major, _, build := version()
- return major >= 10 && build >= 17063
+ var size uint32
+ // First call to get the required buffer size in bytes.
+ // Ignore the error, it will always fail.
+ _, _ = syscall.WSAEnumProtocols(nil, nil, &size)
+ n := int32(size) / int32(unsafe.Sizeof(syscall.WSAProtocolInfo{}))
+ // Second call to get the actual protocols.
+ buf := make([]syscall.WSAProtocolInfo, n)
+ n, err := syscall.WSAEnumProtocols(nil, &buf[0], &size)
+ if err != nil {
+ return false
+ }
+ for i := int32(0); i < n; i++ {
+ if buf[i].AddressFamily == syscall.AF_UNIX {
+ return true
+ }
+ }
+ return false
})
--- /dev/null
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows_test
+
+import (
+ "errors"
+ "internal/syscall/windows"
+ "syscall"
+ "testing"
+)
+
+func TestSupportUnixSocket(t *testing.T) {
+ var d syscall.WSAData
+ if err := syscall.WSAStartup(uint32(0x202), &d); err != nil {
+ t.Fatal(err)
+ }
+ defer syscall.WSACleanup()
+
+ // Test that SupportUnixSocket returns true if WSASocket succeeds with AF_UNIX.
+ got := windows.SupportUnixSocket()
+ s, err := windows.WSASocket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0, nil, 0, windows.WSA_FLAG_NO_HANDLE_INHERIT)
+ if err == nil {
+ syscall.Closesocket(s)
+ }
+ want := !errors.Is(err, windows.WSAEAFNOSUPPORT) && !errors.Is(err, windows.WSAEINVAL)
+ if want != got {
+ t.Errorf("SupportUnixSocket = %v; want %v", got, want)
+ }
+}
"internal/syscall/windows"
"os"
"reflect"
- "runtime"
"testing"
)
-func skipIfUnixSocketNotSupported(t *testing.T) {
- // TODO: the windows.SupportUnixSocket check should be enough, investigate why 386 and arm
- // can't run these tests on newer Windows.
- switch runtime.GOARCH {
- case "386":
- t.Skip("not supported on windows/386, see golang.org/issue/27943")
- case "arm":
- t.Skip("not supported on windows/arm, see golang.org/issue/28061")
- }
+func TestUnixConnLocalWindows(t *testing.T) {
if !windows.SupportUnixSocket() {
t.Skip("unix test")
}
-}
-
-func TestUnixConnLocalWindows(t *testing.T) {
- skipIfUnixSocketNotSupported(t)
handler := func(ls *localServer, ln Listener) {}
for _, laddr := range []string{"", testUnixAddr(t)} {
laddr := laddr
}
func TestModeSocket(t *testing.T) {
- skipIfUnixSocketNotSupported(t)
+ if !windows.SupportUnixSocket() {
+ t.Skip("unix test")
+ }
+
addr := testUnixAddr(t)
l, err := Listen("unix", addr)