github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/sysfs/file_windows.go (about) 1 package sysfs 2 3 import ( 4 "syscall" 5 "unsafe" 6 7 "github.com/wasilibs/wazerox/experimental/sys" 8 ) 9 10 const ( 11 nonBlockingFileReadSupported = true 12 nonBlockingFileWriteSupported = false 13 ) 14 15 var kernel32 = syscall.NewLazyDLL("kernel32.dll") 16 17 // procPeekNamedPipe is the syscall.LazyProc in kernel32 for PeekNamedPipe 18 var procPeekNamedPipe = kernel32.NewProc("PeekNamedPipe") 19 20 // readFd returns ENOSYS on unsupported platforms. 21 // 22 // PeekNamedPipe: https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-peeknamedpipe 23 // "GetFileType can assist in determining what device type the handle refers to. A console handle presents as FILE_TYPE_CHAR." 24 // https://learn.microsoft.com/en-us/windows/console/console-handles 25 func readFd(fd uintptr, buf []byte) (int, sys.Errno) { 26 handle := syscall.Handle(fd) 27 fileType, err := syscall.GetFileType(handle) 28 if err != nil { 29 return 0, sys.UnwrapOSError(err) 30 } 31 if fileType&syscall.FILE_TYPE_CHAR == 0 { 32 return -1, sys.ENOSYS 33 } 34 n, errno := peekNamedPipe(handle) 35 if errno == syscall.ERROR_BROKEN_PIPE { 36 return 0, 0 37 } 38 if n == 0 { 39 return -1, sys.EAGAIN 40 } 41 un, err := syscall.Read(handle, buf[0:n]) 42 return un, sys.UnwrapOSError(err) 43 } 44 45 func writeFd(fd uintptr, buf []byte) (int, sys.Errno) { 46 return -1, sys.ENOSYS 47 } 48 49 func readSocket(h syscall.Handle, buf []byte) (int, sys.Errno) { 50 var overlapped syscall.Overlapped 51 var done uint32 52 errno := syscall.ReadFile(h, buf, &done, &overlapped) 53 if errno == syscall.ERROR_IO_PENDING { 54 errno = sys.EAGAIN 55 } 56 return int(done), sys.UnwrapOSError(errno) 57 } 58 59 func writeSocket(fd uintptr, buf []byte) (int, sys.Errno) { 60 var done uint32 61 var overlapped syscall.Overlapped 62 errno := syscall.WriteFile(syscall.Handle(fd), buf, &done, &overlapped) 63 if errno == syscall.ERROR_IO_PENDING { 64 errno = syscall.EAGAIN 65 } 66 return int(done), sys.UnwrapOSError(errno) 67 } 68 69 // peekNamedPipe partially exposes PeekNamedPipe from the Win32 API 70 // see https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-peeknamedpipe 71 func peekNamedPipe(handle syscall.Handle) (uint32, syscall.Errno) { 72 var totalBytesAvail uint32 73 totalBytesPtr := unsafe.Pointer(&totalBytesAvail) 74 _, _, errno := syscall.SyscallN( 75 procPeekNamedPipe.Addr(), 76 uintptr(handle), // [in] HANDLE hNamedPipe, 77 0, // [out, optional] LPVOID lpBuffer, 78 0, // [in] DWORD nBufferSize, 79 0, // [out, optional] LPDWORD lpBytesRead 80 uintptr(totalBytesPtr), // [out, optional] LPDWORD lpTotalBytesAvail, 81 0) // [out, optional] LPDWORD lpBytesLeftThisMessage 82 return totalBytesAvail, errno 83 } 84 85 func rmdir(path string) sys.Errno { 86 err := syscall.Rmdir(path) 87 return sys.UnwrapOSError(err) 88 }