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  }