1 // Copyright 2017 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
10 "internal/syscall/windows"
24 // This package uses the SetFileCompletionNotificationModes Windows
25 // API to skip calling GetQueuedCompletionStatus if an IO operation
26 // completes synchronously. There is a known bug where
27 // SetFileCompletionNotificationModes crashes on some systems (see
28 // https://support.microsoft.com/kb/2568167 for details).
30 var useSetFileCompletionNotificationModes
bool // determines is SetFileCompletionNotificationModes is present and safe to use
32 // checkSetFileCompletionNotificationModes verifies that
33 // SetFileCompletionNotificationModes Windows API is present
34 // on the system and is safe to use.
35 // See https://support.microsoft.com/kb/2568167 for details.
36 func checkSetFileCompletionNotificationModes() {
37 err
:= syscall
.LoadSetFileCompletionNotificationModes()
41 protos
:= [2]int32{syscall
.IPPROTO_TCP
, 0}
42 var buf
[32]syscall
.WSAProtocolInfo
43 len := uint32(unsafe
.Sizeof(buf
))
44 n
, err
:= syscall
.WSAEnumProtocols(&protos
[0], &buf
[0], &len)
48 for i
:= int32(0); i
< n
; i
++ {
49 if buf
[i
].ServiceFlags1
&syscall
.XP1_IFS_HANDLES
== 0 {
53 useSetFileCompletionNotificationModes
= true
58 e
:= syscall
.WSAStartup(uint32(0x202), &d
)
62 checkSetFileCompletionNotificationModes()
65 // operation contains superset of data necessary to perform all async IO.
66 type operation
struct {
67 // Used by IOCP interface, it must be first field
68 // of the struct, as our code rely on it.
71 // fields used by runtime.netpoll
77 // fields used only by net package
82 rsa
*syscall
.RawSockaddrAny
89 func (o
*operation
) InitBuf(buf
[]byte) {
90 o
.buf
.Len
= uint32(len(buf
))
97 func (o
*operation
) InitBufs(buf
*[][]byte) {
99 o
.bufs
= make([]syscall
.WSABuf
, 0, len(*buf
))
103 for _
, b
:= range *buf
{
105 o
.bufs
= append(o
.bufs
, syscall
.WSABuf
{})
109 o
.bufs
= append(o
.bufs
, syscall
.WSABuf
{Len
: maxRW
, Buf
: &b
[0]})
113 o
.bufs
= append(o
.bufs
, syscall
.WSABuf
{Len
: uint32(len(b
)), Buf
: &b
[0]})
118 // ClearBufs clears all pointers to Buffers parameter captured
119 // by InitBufs, so it can be released by garbage collector.
120 func (o
*operation
) ClearBufs() {
121 for i
:= range o
.bufs
{
127 func (o
*operation
) InitMsg(p
[]byte, oob
[]byte) {
129 o
.msg
.Buffers
= &o
.buf
130 o
.msg
.BufferCount
= 1
136 o
.msg
.Control
.Len
= uint32(len(oob
))
137 o
.msg
.Control
.Buf
= nil
139 o
.msg
.Control
.Buf
= &oob
[0]
143 // execIO executes a single IO operation o. It submits and cancels
144 // IO in the current thread for systems where Windows CancelIoEx API
145 // is available. Alternatively, it passes the request onto
146 // runtime netpoll and waits for completion or cancels request.
147 func execIO(o
*operation
, submit
func(o
*operation
) error
) (int, error
) {
148 if o
.fd
.pd
.runtimeCtx
== 0 {
149 return 0, errors
.New("internal error: polling on unsupported descriptor type")
153 // Notify runtime netpoll about starting IO.
154 err
:= fd
.pd
.prepare(int(o
.mode
), fd
.isFile
)
162 // IO completed immediately
163 if o
.fd
.skipSyncNotif
{
164 // No completion message will follow, so return immediately.
165 return int(o
.qty
), nil
167 // Need to get our completion message anyway.
168 case syscall
.ERROR_IO_PENDING
:
169 // IO started, and we have to wait for its completion.
174 // Wait for our request to complete.
175 err
= fd
.pd
.wait(int(o
.mode
), fd
.isFile
)
177 // All is good. Extract our IO results and return.
179 err
= syscall
.Errno(o
.errno
)
180 // More data available. Return back the size of received data.
181 if err
== syscall
.ERROR_MORE_DATA || err
== windows
.WSAEMSGSIZE
{
182 return int(o
.qty
), err
186 return int(o
.qty
), nil
188 // IO is interrupted by "close" or "timeout"
191 case ErrNetClosing
, ErrFileClosing
, ErrDeadlineExceeded
:
192 // will deal with those.
194 panic("unexpected runtime.netpoll error: " + netpollErr
.Error())
196 // Cancel our request.
197 err
= syscall
.CancelIoEx(fd
.Sysfd
, &o
.o
)
198 // Assuming ERROR_NOT_FOUND is returned, if IO is completed.
199 if err
!= nil && err
!= syscall
.ERROR_NOT_FOUND
{
200 // TODO(brainman): maybe do something else, but panic.
203 // Wait for cancellation to complete.
204 fd
.pd
.waitCanceled(int(o
.mode
))
206 err
= syscall
.Errno(o
.errno
)
207 if err
== syscall
.ERROR_OPERATION_ABORTED
{ // IO Canceled
212 // We issued a cancellation request. But, it seems, IO operation succeeded
213 // before the cancellation request run. We need to treat the IO operation as
214 // succeeded (the bytes are actually sent/recv from network).
215 return int(o
.qty
), nil
218 // FD is a file descriptor. The net and os packages embed this type in
219 // a larger type representing a network connection or OS file.
221 // Lock sysfd and serialize access to Read and Write methods.
224 // System file descriptor. Immutable until Close.
235 // Used to implement pread/pwrite.
239 lastbits
[]byte // first few bytes of the last incomplete rune in last write
240 readuint16
[]uint16 // buffer to hold uint16s obtained with ReadConsole
241 readbyte
[]byte // buffer to hold decoding of readuint16 from utf16 to utf8
242 readbyteOffset
int // readbyte[readOffset:] is yet to be consumed with file.Read
244 // Semaphore signaled when file is closed.
249 // Whether this is a streaming descriptor, as opposed to a
250 // packet-based descriptor like a UDP socket.
253 // Whether a zero byte read indicates EOF. This is false for a
254 // message based socket connection.
257 // Whether this is a file rather than a network socket.
260 // The kind of this file.
264 // fileKind describes the kind of file.
268 kindNet fileKind
= iota
275 // logInitFD is set by tests to enable file descriptor initialization logging.
276 var logInitFD
func(net
string, fd
*FD
, err error
)
278 // Init initializes the FD. The Sysfd field should already be set.
279 // This can be called multiple times on a single FD.
280 // The net argument is a network name from the net package (e.g., "tcp"),
281 // or "file" or "console" or "dir".
282 // Set pollable to true if fd should be managed by runtime netpoll.
283 func (fd
*FD
) Init(net
string, pollable
bool) (string, error
) {
292 fd
.kind
= kindConsole
297 case "tcp", "tcp4", "tcp6",
298 "udp", "udp4", "udp6",
300 "unix", "unixgram", "unixpacket":
303 return "", errors
.New("internal error: unknown network type " + net
)
305 fd
.isFile
= fd
.kind
!= kindNet
309 // Only call init for a network socket.
310 // This means that we don't add files to the runtime poller.
311 // Adding files to the runtime poller can confuse matters
312 // if the user is doing their own overlapped I/O.
315 // In general the code below avoids calling the execIO
316 // function for non-network sockets. If some method does
317 // somehow call execIO, then execIO, and therefore the
318 // calling method, will return an error, because
319 // fd.pd.runtimeCtx will be 0.
322 if logInitFD
!= nil {
323 logInitFD(net
, fd
, err
)
328 if pollable
&& useSetFileCompletionNotificationModes
{
329 // We do not use events, so we can skip them always.
330 flags
:= uint8(syscall
.FILE_SKIP_SET_EVENT_ON_HANDLE
)
331 // It's not safe to skip completion notifications for UDP:
332 // https://docs.microsoft.com/en-us/archive/blogs/winserverperformance/designing-applications-for-high-performance-part-iii
334 flags |
= syscall
.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
336 err
:= syscall
.SetFileCompletionNotificationModes(fd
.Sysfd
, flags
)
337 if err
== nil && flags
&syscall
.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
!= 0 {
338 fd
.skipSyncNotif
= true
341 // Disable SIO_UDP_CONNRESET behavior.
342 // http://support.microsoft.com/kb/263823
344 case "udp", "udp4", "udp6":
347 size
:= uint32(unsafe
.Sizeof(flag
))
348 err
:= syscall
.WSAIoctl(fd
.Sysfd
, syscall
.SIO_UDP_CONNRESET
, (*byte)(unsafe
.Pointer(&flag
)), size
, nil, 0, &ret
, nil, 0)
350 return "wsaioctl", err
357 fd
.rop
.runtimeCtx
= fd
.pd
.runtimeCtx
358 fd
.wop
.runtimeCtx
= fd
.pd
.runtimeCtx
362 func (fd
*FD
) destroy() error
{
363 if fd
.Sysfd
== syscall
.InvalidHandle
{
364 return syscall
.EINVAL
366 // Poller may want to unregister fd in readiness notification mechanism,
367 // so this must be executed before fd.CloseFunc.
372 // The net package uses the CloseFunc variable for testing.
373 err
= CloseFunc(fd
.Sysfd
)
375 err
= syscall
.FindClose(fd
.Sysfd
)
377 err
= syscall
.CloseHandle(fd
.Sysfd
)
379 fd
.Sysfd
= syscall
.InvalidHandle
380 runtime_Semrelease(&fd
.csema
)
384 // Close closes the FD. The underlying file descriptor is closed by
385 // the destroy method when there are no remaining references.
386 func (fd
*FD
) Close() error
{
387 if !fd
.fdmu
.increfAndClose() {
388 return errClosing(fd
.isFile
)
390 if fd
.kind
== kindPipe
{
391 syscall
.CancelIoEx(fd
.Sysfd
, nil)
393 // unblock pending reader and writer
396 // Wait until the descriptor is closed. If this was the only
397 // reference, it is already closed.
398 runtime_Semacquire(&fd
.csema
)
402 // Windows ReadFile and WSARecv use DWORD (uint32) parameter to pass buffer length.
403 // This prevents us reading blocks larger than 4GB.
404 // See golang.org/issue/26923.
405 const maxRW
= 1 << 30 // 1GB is large enough and keeps subsequent reads aligned
407 // Read implements io.Reader.
408 func (fd
*FD
) Read(buf
[]byte) (int, error
) {
409 if err
:= fd
.readLock(); err
!= nil {
412 defer fd
.readUnlock()
414 if len(buf
) > maxRW
{
425 n
, err
= fd
.readConsole(buf
)
427 n
, err
= syscall
.Read(fd
.Sysfd
, buf
)
428 if fd
.kind
== kindPipe
&& err
== syscall
.ERROR_OPERATION_ABORTED
{
429 // Close uses CancelIoEx to interrupt concurrent I/O for pipes.
430 // If the fd is a pipe and the Read was interrupted by CancelIoEx,
431 // we assume it is interrupted by Close.
441 n
, err
= execIO(o
, func(o
*operation
) error
{
442 return syscall
.WSARecv(o
.fd
.Sysfd
, &o
.buf
, 1, &o
.qty
, &o
.flags
, &o
.o
, nil)
445 race
.Acquire(unsafe
.Pointer(&ioSync
))
449 err
= fd
.eofError(n
, err
)
454 var ReadConsole
= syscall
.ReadConsole
// changed for testing
456 // readConsole reads utf16 characters from console File,
457 // encodes them into utf8 and stores them in buffer b.
458 // It returns the number of utf8 bytes read and an error, if any.
459 func (fd
*FD
) readConsole(b
[]byte) (int, error
) {
464 if fd
.readuint16
== nil {
465 // Note: syscall.ReadConsole fails for very large buffers.
466 // The limit is somewhere around (but not exactly) 16384.
468 fd
.readuint16
= make([]uint16, 0, 10000)
469 fd
.readbyte
= make([]byte, 0, 4*cap(fd
.readuint16
))
472 for fd
.readbyteOffset
>= len(fd
.readbyte
) {
473 n
:= cap(fd
.readuint16
) - len(fd
.readuint16
)
478 err
:= ReadConsole(fd
.Sysfd
, &fd
.readuint16
[:len(fd
.readuint16
)+1][len(fd
.readuint16
)], uint32(n
), &nw
, nil)
482 uint16s
:= fd
.readuint16
[:len(fd
.readuint16
)+int(nw
)]
483 fd
.readuint16
= fd
.readuint16
[:0]
484 buf
:= fd
.readbyte
[:0]
485 for i
:= 0; i
< len(uint16s
); i
++ {
486 r
:= rune(uint16s
[i
])
487 if utf16
.IsSurrogate(r
) {
488 if i
+1 == len(uint16s
) {
490 // Save half surrogate pair for next time.
491 fd
.readuint16
= fd
.readuint16
[:1]
492 fd
.readuint16
[0] = uint16(r
)
497 r
= utf16
.DecodeRune(r
, rune(uint16s
[i
+1]))
498 if r
!= utf8
.RuneError
{
503 n
:= utf8
.EncodeRune(buf
[len(buf
):cap(buf
)], r
)
504 buf
= buf
[:len(buf
)+n
]
507 fd
.readbyteOffset
= 0
513 src
:= fd
.readbyte
[fd
.readbyteOffset
:]
515 for i
= 0; i
< len(src
) && i
< len(b
); i
++ {
517 if x
== 0x1A { // Ctrl-Z
525 fd
.readbyteOffset
+= i
529 // Pread emulates the Unix pread system call.
530 func (fd
*FD
) Pread(b
[]byte, off
int64) (int, error
) {
531 // Call incref, not readLock, because since pread specifies the
532 // offset it is independent from other reads.
533 if err
:= fd
.incref(); err
!= nil {
544 curoffset
, e
:= syscall
.Seek(fd
.Sysfd
, 0, io
.SeekCurrent
)
548 defer syscall
.Seek(fd
.Sysfd
, curoffset
, io
.SeekStart
)
549 o
:= syscall
.Overlapped
{
550 OffsetHigh
: uint32(off
>> 32),
554 e
= syscall
.ReadFile(fd
.Sysfd
, b
, &done
, &o
)
557 if e
== syscall
.ERROR_HANDLE_EOF
{
562 e
= fd
.eofError(int(done
), e
)
567 // ReadFrom wraps the recvfrom network call.
568 func (fd
*FD
) ReadFrom(buf
[]byte) (int, syscall
.Sockaddr
, error
) {
572 if len(buf
) > maxRW
{
575 if err
:= fd
.readLock(); err
!= nil {
578 defer fd
.readUnlock()
581 n
, err
:= execIO(o
, func(o
*operation
) error
{
583 o
.rsa
= new(syscall
.RawSockaddrAny
)
585 o
.rsan
= int32(unsafe
.Sizeof(*o
.rsa
))
586 return syscall
.WSARecvFrom(o
.fd
.Sysfd
, &o
.buf
, 1, &o
.qty
, &o
.flags
, o
.rsa
, &o
.rsan
, &o
.o
, nil)
588 err
= fd
.eofError(n
, err
)
592 sa
, _
:= o
.rsa
.Sockaddr()
596 // ReadFromInet4 wraps the recvfrom network call for IPv4.
597 func (fd
*FD
) ReadFromInet4(buf
[]byte, sa4
*syscall
.SockaddrInet4
) (int, error
) {
601 if len(buf
) > maxRW
{
604 if err
:= fd
.readLock(); err
!= nil {
607 defer fd
.readUnlock()
610 n
, err
:= execIO(o
, func(o
*operation
) error
{
612 o
.rsa
= new(syscall
.RawSockaddrAny
)
614 o
.rsan
= int32(unsafe
.Sizeof(*o
.rsa
))
615 return syscall
.WSARecvFrom(o
.fd
.Sysfd
, &o
.buf
, 1, &o
.qty
, &o
.flags
, o
.rsa
, &o
.rsan
, &o
.o
, nil)
617 err
= fd
.eofError(n
, err
)
621 rawToSockaddrInet4(o
.rsa
, sa4
)
625 // ReadFromInet6 wraps the recvfrom network call for IPv6.
626 func (fd
*FD
) ReadFromInet6(buf
[]byte, sa6
*syscall
.SockaddrInet6
) (int, error
) {
630 if len(buf
) > maxRW
{
633 if err
:= fd
.readLock(); err
!= nil {
636 defer fd
.readUnlock()
639 n
, err
:= execIO(o
, func(o
*operation
) error
{
641 o
.rsa
= new(syscall
.RawSockaddrAny
)
643 o
.rsan
= int32(unsafe
.Sizeof(*o
.rsa
))
644 return syscall
.WSARecvFrom(o
.fd
.Sysfd
, &o
.buf
, 1, &o
.qty
, &o
.flags
, o
.rsa
, &o
.rsan
, &o
.o
, nil)
646 err
= fd
.eofError(n
, err
)
650 rawToSockaddrInet6(o
.rsa
, sa6
)
654 // Write implements io.Writer.
655 func (fd
*FD
) Write(buf
[]byte) (int, error
) {
656 if err
:= fd
.writeLock(); err
!= nil {
659 defer fd
.writeUnlock()
676 n
, err
= fd
.writeConsole(b
)
678 n
, err
= syscall
.Write(fd
.Sysfd
, b
)
679 if fd
.kind
== kindPipe
&& err
== syscall
.ERROR_OPERATION_ABORTED
{
680 // Close uses CancelIoEx to interrupt concurrent I/O for pipes.
681 // If the fd is a pipe and the Write was interrupted by CancelIoEx,
682 // we assume it is interrupted by Close.
691 race
.ReleaseMerge(unsafe
.Pointer(&ioSync
))
695 n
, err
= execIO(o
, func(o
*operation
) error
{
696 return syscall
.WSASend(o
.fd
.Sysfd
, &o
.buf
, 1, &o
.qty
, 0, &o
.o
, nil)
708 // writeConsole writes len(b) bytes to the console File.
709 // It returns the number of bytes written and an error, if any.
710 func (fd
*FD
) writeConsole(b
[]byte) (int, error
) {
712 runes
:= make([]rune
, 0, 256)
713 if len(fd
.lastbits
) > 0 {
714 b
= append(fd
.lastbits
, b
...)
718 for len(b
) >= utf8
.UTFMax || utf8
.FullRune(b
) {
719 r
, l
:= utf8
.DecodeRune(b
)
720 runes
= append(runes
, r
)
724 fd
.lastbits
= make([]byte, len(b
))
727 // syscall.WriteConsole seems to fail, if given large buffer.
728 // So limit the buffer to 16000 characters. This number was
729 // discovered by experimenting with syscall.WriteConsole.
730 const maxWrite
= 16000
738 uint16s
:= utf16
.Encode(chunk
)
739 for len(uint16s
) > 0 {
741 err
:= syscall
.WriteConsole(fd
.Sysfd
, &uint16s
[0], uint32(len(uint16s
)), &written
, nil)
745 uint16s
= uint16s
[written
:]
751 // Pwrite emulates the Unix pwrite system call.
752 func (fd
*FD
) Pwrite(buf
[]byte, off
int64) (int, error
) {
753 // Call incref, not writeLock, because since pwrite specifies the
754 // offset it is independent from other writes.
755 if err
:= fd
.incref(); err
!= nil {
762 curoffset
, e
:= syscall
.Seek(fd
.Sysfd
, 0, io
.SeekCurrent
)
766 defer syscall
.Seek(fd
.Sysfd
, curoffset
, io
.SeekStart
)
775 o
:= syscall
.Overlapped
{
776 OffsetHigh
: uint32(off
>> 32),
779 e
= syscall
.WriteFile(fd
.Sysfd
, b
, &n
, &o
)
790 // Writev emulates the Unix writev system call.
791 func (fd
*FD
) Writev(buf
*[][]byte) (int64, error
) {
795 if err
:= fd
.writeLock(); err
!= nil {
798 defer fd
.writeUnlock()
800 race
.ReleaseMerge(unsafe
.Pointer(&ioSync
))
804 n
, err
:= execIO(o
, func(o
*operation
) error
{
805 return syscall
.WSASend(o
.fd
.Sysfd
, &o
.bufs
[0], uint32(len(o
.bufs
)), &o
.qty
, 0, &o
.o
, nil)
809 consume(buf
, int64(n
))
813 // WriteTo wraps the sendto network call.
814 func (fd
*FD
) WriteTo(buf
[]byte, sa syscall
.Sockaddr
) (int, error
) {
815 if err
:= fd
.writeLock(); err
!= nil {
818 defer fd
.writeUnlock()
821 // handle zero-byte payload
825 n
, err
:= execIO(o
, func(o
*operation
) error
{
826 return syscall
.WSASendto(o
.fd
.Sysfd
, &o
.buf
, 1, &o
.qty
, 0, o
.sa
, &o
.o
, nil)
840 n
, err
:= execIO(o
, func(o
*operation
) error
{
841 return syscall
.WSASendto(o
.fd
.Sysfd
, &o
.buf
, 1, &o
.qty
, 0, o
.sa
, &o
.o
, nil)
852 // WriteToInet4 is WriteTo, specialized for syscall.SockaddrInet4.
853 func (fd
*FD
) WriteToInet4(buf
[]byte, sa4
*syscall
.SockaddrInet4
) (int, error
) {
854 if err
:= fd
.writeLock(); err
!= nil {
857 defer fd
.writeUnlock()
860 // handle zero-byte payload
863 n
, err
:= execIO(o
, func(o
*operation
) error
{
864 return windows
.WSASendtoInet4(o
.fd
.Sysfd
, &o
.buf
, 1, &o
.qty
, 0, sa4
, &o
.o
, nil)
877 n
, err
:= execIO(o
, func(o
*operation
) error
{
878 return windows
.WSASendtoInet4(o
.fd
.Sysfd
, &o
.buf
, 1, &o
.qty
, 0, sa4
, &o
.o
, nil)
889 // WriteToInet6 is WriteTo, specialized for syscall.SockaddrInet6.
890 func (fd
*FD
) WriteToInet6(buf
[]byte, sa6
*syscall
.SockaddrInet6
) (int, error
) {
891 if err
:= fd
.writeLock(); err
!= nil {
894 defer fd
.writeUnlock()
897 // handle zero-byte payload
900 n
, err
:= execIO(o
, func(o
*operation
) error
{
901 return windows
.WSASendtoInet6(o
.fd
.Sysfd
, &o
.buf
, 1, &o
.qty
, 0, sa6
, &o
.o
, nil)
914 n
, err
:= execIO(o
, func(o
*operation
) error
{
915 return windows
.WSASendtoInet6(o
.fd
.Sysfd
, &o
.buf
, 1, &o
.qty
, 0, sa6
, &o
.o
, nil)
926 // Call ConnectEx. This doesn't need any locking, since it is only
927 // called when the descriptor is first created. This is here rather
928 // than in the net package so that it can use fd.wop.
929 func (fd
*FD
) ConnectEx(ra syscall
.Sockaddr
) error
{
932 _
, err
:= execIO(o
, func(o
*operation
) error
{
933 return ConnectExFunc(o
.fd
.Sysfd
, o
.sa
, nil, 0, nil, &o
.o
)
938 func (fd
*FD
) acceptOne(s syscall
.Handle
, rawsa
[]syscall
.RawSockaddrAny
, o
*operation
) (string, error
) {
939 // Submit accept request.
941 o
.rsan
= int32(unsafe
.Sizeof(rawsa
[0]))
942 _
, err
:= execIO(o
, func(o
*operation
) error
{
943 return AcceptFunc(o
.fd
.Sysfd
, o
.handle
, (*byte)(unsafe
.Pointer(&rawsa
[0])), 0, uint32(o
.rsan
), uint32(o
.rsan
), &o
.qty
, &o
.o
)
947 return "acceptex", err
950 // Inherit properties of the listening socket.
951 err
= syscall
.Setsockopt(s
, syscall
.SOL_SOCKET
, syscall
.SO_UPDATE_ACCEPT_CONTEXT
, (*byte)(unsafe
.Pointer(&fd
.Sysfd
)), int32(unsafe
.Sizeof(fd
.Sysfd
)))
954 return "setsockopt", err
960 // Accept handles accepting a socket. The sysSocket parameter is used
961 // to allocate the net socket.
962 func (fd
*FD
) Accept(sysSocket
func() (syscall
.Handle
, error
)) (syscall
.Handle
, []syscall
.RawSockaddrAny
, uint32, string, error
) {
963 if err
:= fd
.readLock(); err
!= nil {
964 return syscall
.InvalidHandle
, nil, 0, "", err
966 defer fd
.readUnlock()
969 var rawsa
[2]syscall
.RawSockaddrAny
971 s
, err
:= sysSocket()
973 return syscall
.InvalidHandle
, nil, 0, "", err
976 errcall
, err
:= fd
.acceptOne(s
, rawsa
[:], o
)
978 return s
, rawsa
[:], uint32(o
.rsan
), "", nil
981 // Sometimes we see WSAECONNRESET and ERROR_NETNAME_DELETED is
982 // returned here. These happen if connection reset is received
983 // before AcceptEx could complete. These errors relate to new
984 // connection, not to AcceptEx, so ignore broken connection and
985 // try AcceptEx again for more connections.
986 errno
, ok
:= err
.(syscall
.Errno
)
988 return syscall
.InvalidHandle
, nil, 0, errcall
, err
991 case syscall
.ERROR_NETNAME_DELETED
, syscall
.WSAECONNRESET
:
992 // ignore these and try again
994 return syscall
.InvalidHandle
, nil, 0, errcall
, err
999 // Seek wraps syscall.Seek.
1000 func (fd
*FD
) Seek(offset
int64, whence
int) (int64, error
) {
1001 if err
:= fd
.incref(); err
!= nil {
1009 return syscall
.Seek(fd
.Sysfd
, offset
, whence
)
1012 // FindNextFile wraps syscall.FindNextFile.
1013 func (fd
*FD
) FindNextFile(data
*syscall
.Win32finddata
) error
{
1014 if err
:= fd
.incref(); err
!= nil {
1018 return syscall
.FindNextFile(fd
.Sysfd
, data
)
1021 // Fchmod updates syscall.ByHandleFileInformation.Fileattributes when needed.
1022 func (fd
*FD
) Fchmod(mode
uint32) error
{
1023 if err
:= fd
.incref(); err
!= nil {
1028 var d syscall
.ByHandleFileInformation
1029 if err
:= syscall
.GetFileInformationByHandle(fd
.Sysfd
, &d
); err
!= nil {
1032 attrs
:= d
.FileAttributes
1033 if mode
&syscall
.S_IWRITE
!= 0 {
1034 attrs
&^= syscall
.FILE_ATTRIBUTE_READONLY
1036 attrs |
= syscall
.FILE_ATTRIBUTE_READONLY
1038 if attrs
== d
.FileAttributes
{
1042 var du windows
.FILE_BASIC_INFO
1043 du
.FileAttributes
= attrs
1044 l
:= uint32(unsafe
.Sizeof(d
))
1045 return windows
.SetFileInformationByHandle(fd
.Sysfd
, windows
.FileBasicInfo
, uintptr(unsafe
.Pointer(&du
)), l
)
1048 // Fchdir wraps syscall.Fchdir.
1049 func (fd
*FD
) Fchdir() error
{
1050 if err
:= fd
.incref(); err
!= nil {
1054 return syscall
.Fchdir(fd
.Sysfd
)
1057 // GetFileType wraps syscall.GetFileType.
1058 func (fd
*FD
) GetFileType() (uint32, error
) {
1059 if err
:= fd
.incref(); err
!= nil {
1063 return syscall
.GetFileType(fd
.Sysfd
)
1066 // GetFileInformationByHandle wraps GetFileInformationByHandle.
1067 func (fd
*FD
) GetFileInformationByHandle(data
*syscall
.ByHandleFileInformation
) error
{
1068 if err
:= fd
.incref(); err
!= nil {
1072 return syscall
.GetFileInformationByHandle(fd
.Sysfd
, data
)
1075 // RawRead invokes the user-defined function f for a read operation.
1076 func (fd
*FD
) RawRead(f
func(uintptr) bool) error
{
1077 if err
:= fd
.readLock(); err
!= nil {
1080 defer fd
.readUnlock()
1082 if f(uintptr(fd
.Sysfd
)) {
1086 // Use a zero-byte read as a way to get notified when this
1087 // socket is readable. h/t https://stackoverflow.com/a/42019668/332798
1091 o
.flags |
= windows
.MSG_PEEK
1093 _
, err
:= execIO(o
, func(o
*operation
) error
{
1094 return syscall
.WSARecv(o
.fd
.Sysfd
, &o
.buf
, 1, &o
.qty
, &o
.flags
, &o
.o
, nil)
1096 if err
== windows
.WSAEMSGSIZE
{
1097 // expected with a 0-byte peek, ignore.
1098 } else if err
!= nil {
1104 // RawWrite invokes the user-defined function f for a write operation.
1105 func (fd
*FD
) RawWrite(f
func(uintptr) bool) error
{
1106 if err
:= fd
.writeLock(); err
!= nil {
1109 defer fd
.writeUnlock()
1111 if f(uintptr(fd
.Sysfd
)) {
1115 // TODO(tmm1): find a way to detect socket writability
1116 return syscall
.EWINDOWS
1119 func sockaddrInet4ToRaw(rsa
*syscall
.RawSockaddrAny
, sa
*syscall
.SockaddrInet4
) int32 {
1120 *rsa
= syscall
.RawSockaddrAny
{}
1121 raw
:= (*syscall
.RawSockaddrInet4
)(unsafe
.Pointer(rsa
))
1122 raw
.Family
= syscall
.AF_INET
1123 p
:= (*[2]byte)(unsafe
.Pointer(&raw
.Port
))
1124 p
[0] = byte(sa
.Port
>> 8)
1125 p
[1] = byte(sa
.Port
)
1127 return int32(unsafe
.Sizeof(*raw
))
1130 func sockaddrInet6ToRaw(rsa
*syscall
.RawSockaddrAny
, sa
*syscall
.SockaddrInet6
) int32 {
1131 *rsa
= syscall
.RawSockaddrAny
{}
1132 raw
:= (*syscall
.RawSockaddrInet6
)(unsafe
.Pointer(rsa
))
1133 raw
.Family
= syscall
.AF_INET6
1134 p
:= (*[2]byte)(unsafe
.Pointer(&raw
.Port
))
1135 p
[0] = byte(sa
.Port
>> 8)
1136 p
[1] = byte(sa
.Port
)
1137 raw
.Scope_id
= sa
.ZoneId
1139 return int32(unsafe
.Sizeof(*raw
))
1142 func rawToSockaddrInet4(rsa
*syscall
.RawSockaddrAny
, sa
*syscall
.SockaddrInet4
) {
1143 pp
:= (*syscall
.RawSockaddrInet4
)(unsafe
.Pointer(rsa
))
1144 p
:= (*[2]byte)(unsafe
.Pointer(&pp
.Port
))
1145 sa
.Port
= int(p
[0])<<8 + int(p
[1])
1149 func rawToSockaddrInet6(rsa
*syscall
.RawSockaddrAny
, sa
*syscall
.SockaddrInet6
) {
1150 pp
:= (*syscall
.RawSockaddrInet6
)(unsafe
.Pointer(rsa
))
1151 p
:= (*[2]byte)(unsafe
.Pointer(&pp
.Port
))
1152 sa
.Port
= int(p
[0])<<8 + int(p
[1])
1153 sa
.ZoneId
= pp
.Scope_id
1157 func sockaddrToRaw(rsa
*syscall
.RawSockaddrAny
, sa syscall
.Sockaddr
) (int32, error
) {
1158 switch sa
:= sa
.(type) {
1159 case *syscall
.SockaddrInet4
:
1160 sz
:= sockaddrInet4ToRaw(rsa
, sa
)
1162 case *syscall
.SockaddrInet6
:
1163 sz
:= sockaddrInet6ToRaw(rsa
, sa
)
1166 return 0, syscall
.EWINDOWS
1170 // ReadMsg wraps the WSARecvMsg network call.
1171 func (fd
*FD
) ReadMsg(p
[]byte, oob
[]byte, flags
int) (int, int, int, syscall
.Sockaddr
, error
) {
1172 if err
:= fd
.readLock(); err
!= nil {
1173 return 0, 0, 0, nil, err
1175 defer fd
.readUnlock()
1184 o
.rsa
= new(syscall
.RawSockaddrAny
)
1186 o
.msg
.Name
= (syscall
.Pointer
)(unsafe
.Pointer(o
.rsa
))
1187 o
.msg
.Namelen
= int32(unsafe
.Sizeof(*o
.rsa
))
1188 o
.msg
.Flags
= uint32(flags
)
1189 n
, err
:= execIO(o
, func(o
*operation
) error
{
1190 return windows
.WSARecvMsg(o
.fd
.Sysfd
, &o
.msg
, &o
.qty
, &o
.o
, nil)
1192 err
= fd
.eofError(n
, err
)
1193 var sa syscall
.Sockaddr
1195 sa
, err
= o
.rsa
.Sockaddr()
1197 return n
, int(o
.msg
.Control
.Len
), int(o
.msg
.Flags
), sa
, err
1200 // ReadMsgInet4 is ReadMsg, but specialized to return a syscall.SockaddrInet4.
1201 func (fd
*FD
) ReadMsgInet4(p
[]byte, oob
[]byte, flags
int, sa4
*syscall
.SockaddrInet4
) (int, int, int, error
) {
1202 if err
:= fd
.readLock(); err
!= nil {
1205 defer fd
.readUnlock()
1214 o
.rsa
= new(syscall
.RawSockaddrAny
)
1216 o
.msg
.Name
= (syscall
.Pointer
)(unsafe
.Pointer(o
.rsa
))
1217 o
.msg
.Namelen
= int32(unsafe
.Sizeof(*o
.rsa
))
1218 o
.msg
.Flags
= uint32(flags
)
1219 n
, err
:= execIO(o
, func(o
*operation
) error
{
1220 return windows
.WSARecvMsg(o
.fd
.Sysfd
, &o
.msg
, &o
.qty
, &o
.o
, nil)
1222 err
= fd
.eofError(n
, err
)
1224 rawToSockaddrInet4(o
.rsa
, sa4
)
1226 return n
, int(o
.msg
.Control
.Len
), int(o
.msg
.Flags
), err
1229 // ReadMsgInet6 is ReadMsg, but specialized to return a syscall.SockaddrInet6.
1230 func (fd
*FD
) ReadMsgInet6(p
[]byte, oob
[]byte, flags
int, sa6
*syscall
.SockaddrInet6
) (int, int, int, error
) {
1231 if err
:= fd
.readLock(); err
!= nil {
1234 defer fd
.readUnlock()
1243 o
.rsa
= new(syscall
.RawSockaddrAny
)
1245 o
.msg
.Name
= (syscall
.Pointer
)(unsafe
.Pointer(o
.rsa
))
1246 o
.msg
.Namelen
= int32(unsafe
.Sizeof(*o
.rsa
))
1247 o
.msg
.Flags
= uint32(flags
)
1248 n
, err
:= execIO(o
, func(o
*operation
) error
{
1249 return windows
.WSARecvMsg(o
.fd
.Sysfd
, &o
.msg
, &o
.qty
, &o
.o
, nil)
1251 err
= fd
.eofError(n
, err
)
1253 rawToSockaddrInet6(o
.rsa
, sa6
)
1255 return n
, int(o
.msg
.Control
.Len
), int(o
.msg
.Flags
), err
1258 // WriteMsg wraps the WSASendMsg network call.
1259 func (fd
*FD
) WriteMsg(p
[]byte, oob
[]byte, sa syscall
.Sockaddr
) (int, int, error
) {
1261 return 0, 0, errors
.New("packet is too large (only 1GB is allowed)")
1264 if err
:= fd
.writeLock(); err
!= nil {
1267 defer fd
.writeUnlock()
1273 o
.rsa
= new(syscall
.RawSockaddrAny
)
1275 len, err
:= sockaddrToRaw(o
.rsa
, sa
)
1279 o
.msg
.Name
= (syscall
.Pointer
)(unsafe
.Pointer(o
.rsa
))
1282 n
, err
:= execIO(o
, func(o
*operation
) error
{
1283 return windows
.WSASendMsg(o
.fd
.Sysfd
, &o
.msg
, 0, &o
.qty
, &o
.o
, nil)
1285 return n
, int(o
.msg
.Control
.Len
), err
1288 // WriteMsgInet4 is WriteMsg specialized for syscall.SockaddrInet4.
1289 func (fd
*FD
) WriteMsgInet4(p
[]byte, oob
[]byte, sa
*syscall
.SockaddrInet4
) (int, int, error
) {
1291 return 0, 0, errors
.New("packet is too large (only 1GB is allowed)")
1294 if err
:= fd
.writeLock(); err
!= nil {
1297 defer fd
.writeUnlock()
1302 o
.rsa
= new(syscall
.RawSockaddrAny
)
1304 len := sockaddrInet4ToRaw(o
.rsa
, sa
)
1305 o
.msg
.Name
= (syscall
.Pointer
)(unsafe
.Pointer(o
.rsa
))
1307 n
, err
:= execIO(o
, func(o
*operation
) error
{
1308 return windows
.WSASendMsg(o
.fd
.Sysfd
, &o
.msg
, 0, &o
.qty
, &o
.o
, nil)
1310 return n
, int(o
.msg
.Control
.Len
), err
1313 // WriteMsgInet6 is WriteMsg specialized for syscall.SockaddrInet6.
1314 func (fd
*FD
) WriteMsgInet6(p
[]byte, oob
[]byte, sa
*syscall
.SockaddrInet6
) (int, int, error
) {
1316 return 0, 0, errors
.New("packet is too large (only 1GB is allowed)")
1319 if err
:= fd
.writeLock(); err
!= nil {
1322 defer fd
.writeUnlock()
1327 o
.rsa
= new(syscall
.RawSockaddrAny
)
1329 len := sockaddrInet6ToRaw(o
.rsa
, sa
)
1330 o
.msg
.Name
= (syscall
.Pointer
)(unsafe
.Pointer(o
.rsa
))
1332 n
, err
:= execIO(o
, func(o
*operation
) error
{
1333 return windows
.WSASendMsg(o
.fd
.Sysfd
, &o
.msg
, 0, &o
.qty
, &o
.o
, nil)
1335 return n
, int(o
.msg
.Control
.Len
), err