github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/sysfs/sock_windows.go (about) 1 //go:build windows 2 3 package sysfs 4 5 import ( 6 "net" 7 "syscall" 8 "unsafe" 9 10 "github.com/bananabytelabs/wazero/experimental/sys" 11 "github.com/bananabytelabs/wazero/internal/fsapi" 12 socketapi "github.com/bananabytelabs/wazero/internal/sock" 13 ) 14 15 const ( 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 23 var ( 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 32 func 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`. 42 func 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 58 func 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 72 func _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 }