1//go:build windows
2
3package sysfs
4
5import (
6 "net"
7 "syscall"
8 "unsafe"
9
10 "github.com/tetratelabs/wazero/experimental/sys"
11 "github.com/tetratelabs/wazero/internal/fsapi"
12 socketapi "github.com/tetratelabs/wazero/internal/sock"
13)
14
15const (
16 // MSG_PEEK is the flag PEEK for syscall.Recvfrom on Windows.
17 // This constant is not exported on this platform.
18 MSG_PEEK = 0x2
19 // _FIONBIO is the flag to set the O_NONBLOCK flag on socket handles using ioctlsocket.
20 _FIONBIO = 0x8004667e
21)
22
23var (
24 // modws2_32 is WinSock.
25 modws2_32 = syscall.NewLazyDLL("ws2_32.dll")
26 // procrecvfrom exposes recvfrom from WinSock.
27 procrecvfrom = modws2_32.NewProc("recvfrom")
28 // procioctlsocket exposes ioctlsocket from WinSock.
29 procioctlsocket = modws2_32.NewProc("ioctlsocket")
30)
31
32func newTCPListenerFile(tl *net.TCPListener) socketapi.TCPSock {
33 return newDefaultTCPListenerFile(tl)
34}
35
36// recvfrom exposes the underlying syscall in Windows.
37//
38// Note: since we are only using this to expose MSG_PEEK,
39// we do not need really need all the parameters that are actually
40// allowed in WinSock.
41// We ignore `from *sockaddr` and `fromlen *int`.
42func recvfrom(s uintptr, buf []byte, flags int32) (n int, errno sys.Errno) {
43 var _p0 *byte
44 if len(buf) > 0 {
45 _p0 = &buf[0]
46 }
47 r0, _, e1 := syscall.SyscallN(
48 procrecvfrom.Addr(),
49 s,
50 uintptr(unsafe.Pointer(_p0)),
51 uintptr(len(buf)),
52 uintptr(flags),
53 0, // from *sockaddr (optional)
54 0) // fromlen *int (optional)
55 return int(r0), sys.UnwrapOSError(e1)
56}
57
58func setNonblockSocket(fd uintptr, enabled bool) sys.Errno {
59 opt := uint64(0)
60 if enabled {
61 opt = 1
62 }
63 // ioctlsocket(fd, FIONBIO, &opt)
64 _, _, errno := syscall.SyscallN(
65 procioctlsocket.Addr(),
66 uintptr(fd),
67 uintptr(_FIONBIO),
68 uintptr(unsafe.Pointer(&opt)))
69 return sys.UnwrapOSError(errno)
70}
71
72func _pollSock(conn syscall.Conn, flag fsapi.Pflag, timeoutMillis int32) (bool, sys.Errno) {
73 if flag != fsapi.POLLIN {
74 return false, sys.ENOTSUP
75 }
76 n, errno := syscallConnControl(conn, func(fd uintptr) (int, sys.Errno) {
77 return _poll([]pollFd{newPollFd(fd, _POLLIN, 0)}, timeoutMillis)
78 })
79 return n > 0, errno
80}