fd_windows.mx raw

   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.
   4  
   5  package poll
   6  
   7  import (
   8  	"errors"
   9  	"internal/race"
  10  	"internal/syscall/windows"
  11  	"io"
  12  	"sync"
  13  	"sync/atomic"
  14  	"syscall"
  15  	"unicode/utf16"
  16  	"unicode/utf8"
  17  	"unsafe"
  18  )
  19  
  20  var (
  21  	initErr error
  22  	ioSync  uint64
  23  )
  24  
  25  // This package uses the SetFileCompletionNotificationModes Windows
  26  // API to skip calling GetQueuedCompletionStatus if an IO operation
  27  // completes synchronously. There is a known bug where
  28  // SetFileCompletionNotificationModes crashes on some systems (see
  29  // https://support.microsoft.com/kb/2568167 for details).
  30  
  31  var socketCanUseSetFileCompletionNotificationModes bool // determines is SetFileCompletionNotificationModes is present and sockets can safely use it
  32  
  33  // checkSetFileCompletionNotificationModes verifies that
  34  // SetFileCompletionNotificationModes Windows API is present
  35  // on the system and is safe to use.
  36  // See https://support.microsoft.com/kb/2568167 for details.
  37  func checkSetFileCompletionNotificationModes() {
  38  	err := syscall.LoadSetFileCompletionNotificationModes()
  39  	if err != nil {
  40  		return
  41  	}
  42  	protos := [2]int32{syscall.IPPROTO_TCP, 0}
  43  	var buf [32]syscall.WSAProtocolInfo
  44  	len := uint32(unsafe.Sizeof(buf))
  45  	n, err := syscall.WSAEnumProtocols(&protos[0], &buf[0], &len)
  46  	if err != nil {
  47  		return
  48  	}
  49  	for i := int32(0); i < n; i++ {
  50  		if buf[i].ServiceFlags1&syscall.XP1_IFS_HANDLES == 0 {
  51  			return
  52  		}
  53  	}
  54  	socketCanUseSetFileCompletionNotificationModes = true
  55  }
  56  
  57  // InitWSA initiates the use of the Winsock DLL by the current process.
  58  // It is called from the net package at init time to avoid
  59  // loading ws2_32.dll when net is not used.
  60  var InitWSA = sync.OnceFunc(func() {
  61  	var d syscall.WSAData
  62  	e := syscall.WSAStartup(uint32(0x202), &d)
  63  	if e != nil {
  64  		initErr = e
  65  	}
  66  	checkSetFileCompletionNotificationModes()
  67  })
  68  
  69  // operation contains superset of data necessary to perform all async IO.
  70  type operation struct {
  71  	// Used by IOCP interface, it must be first field
  72  	// of the struct, as our code relies on it.
  73  	o syscall.Overlapped
  74  
  75  	// fields used by runtime.netpoll
  76  	runtimeCtx uintptr
  77  	mode       int32
  78  
  79  	// fields used only by net package
  80  	fd     *FD
  81  	buf    syscall.WSABuf
  82  	msg    windows.WSAMsg
  83  	sa     syscall.Sockaddr
  84  	rsa    *syscall.RawSockaddrAny
  85  	rsan   int32
  86  	handle syscall.Handle
  87  	flags  uint32
  88  	qty    uint32
  89  	bufs   []syscall.WSABuf
  90  }
  91  
  92  func (o *operation) setEvent() {
  93  	h, err := windows.CreateEvent(nil, 0, 0, nil)
  94  	if err != nil {
  95  		// This shouldn't happen when all CreateEvent arguments are zero.
  96  		panic(err)
  97  	}
  98  	// Set the low bit so that the external IOCP doesn't receive the completion packet.
  99  	o.o.HEvent = h | 1
 100  }
 101  
 102  func (o *operation) close() {
 103  	if o.o.HEvent != 0 {
 104  		syscall.CloseHandle(o.o.HEvent)
 105  	}
 106  }
 107  
 108  func (o *operation) overlapped() *syscall.Overlapped {
 109  	if o.fd.isBlocking {
 110  		// Don't return the overlapped object if the file handle
 111  		// doesn't use overlapped I/O. It could be used, but
 112  		// that would then use the file pointer stored in the
 113  		// overlapped object rather than the real file pointer.
 114  		return nil
 115  	}
 116  	return &o.o
 117  }
 118  
 119  func (o *operation) InitBuf(buf []byte) {
 120  	o.buf.Len = uint32(len(buf))
 121  	o.buf.Buf = nil
 122  	if len(buf) != 0 {
 123  		o.buf.Buf = &buf[0]
 124  	}
 125  }
 126  
 127  func (o *operation) InitBufs(buf *[][]byte) {
 128  	if o.bufs == nil {
 129  		o.bufs = []syscall.WSABuf{:0:len(*buf)}
 130  	} else {
 131  		o.bufs = o.bufs[:0]
 132  	}
 133  	for _, b := range *buf {
 134  		if len(b) == 0 {
 135  			o.bufs = append(o.bufs, syscall.WSABuf{})
 136  			continue
 137  		}
 138  		for len(b) > maxRW {
 139  			o.bufs = append(o.bufs, syscall.WSABuf{Len: maxRW, Buf: &b[0]})
 140  			b = b[maxRW:]
 141  		}
 142  		if len(b) > 0 {
 143  			o.bufs = append(o.bufs, syscall.WSABuf{Len: uint32(len(b)), Buf: &b[0]})
 144  		}
 145  	}
 146  }
 147  
 148  // ClearBufs clears all pointers to Buffers parameter captured
 149  // by InitBufs, so it can be released by garbage collector.
 150  func (o *operation) ClearBufs() {
 151  	for i := range o.bufs {
 152  		o.bufs[i].Buf = nil
 153  	}
 154  	o.bufs = o.bufs[:0]
 155  }
 156  
 157  func (o *operation) InitMsg(p []byte, oob []byte) {
 158  	o.InitBuf(p)
 159  	o.msg.Buffers = &o.buf
 160  	o.msg.BufferCount = 1
 161  
 162  	o.msg.Name = nil
 163  	o.msg.Namelen = 0
 164  
 165  	o.msg.Flags = 0
 166  	o.msg.Control.Len = uint32(len(oob))
 167  	o.msg.Control.Buf = nil
 168  	if len(oob) != 0 {
 169  		o.msg.Control.Buf = &oob[0]
 170  	}
 171  }
 172  
 173  // waitIO waits for the IO operation o to complete.
 174  func waitIO(o *operation) error {
 175  	if o.fd.isBlocking {
 176  		panic("can't wait on blocking operations")
 177  	}
 178  	fd := o.fd
 179  	if !fd.pollable() {
 180  		// The overlapped handle is not added to the runtime poller,
 181  		// the only way to wait for the IO to complete is block until
 182  		// the overlapped event is signaled.
 183  		_, err := syscall.WaitForSingleObject(o.o.HEvent, syscall.INFINITE)
 184  		return err
 185  	}
 186  	// Wait for our request to complete.
 187  	err := fd.pd.wait(int(o.mode), fd.isFile)
 188  	switch err {
 189  	case nil, ErrNetClosing, ErrFileClosing, ErrDeadlineExceeded:
 190  		// No other error is expected.
 191  	default:
 192  		panic("unexpected runtime.netpoll error: " + err.Error())
 193  	}
 194  	return err
 195  }
 196  
 197  // cancelIO cancels the IO operation o and waits for it to complete.
 198  func cancelIO(o *operation) {
 199  	fd := o.fd
 200  	if !fd.pollable() {
 201  		return
 202  	}
 203  	// Cancel our request.
 204  	err := syscall.CancelIoEx(fd.Sysfd, &o.o)
 205  	// Assuming ERROR_NOT_FOUND is returned, if IO is completed.
 206  	if err != nil && err != syscall.ERROR_NOT_FOUND {
 207  		// TODO(brainman): maybe do something else, but panic.
 208  		panic(err)
 209  	}
 210  	fd.pd.waitCanceled(int(o.mode))
 211  }
 212  
 213  // execIO executes a single IO operation o.
 214  // It supports both synchronous and asynchronous IO.
 215  // o.qty and o.flags are set to zero before calling submit
 216  // to avoid reusing the values from a previous call.
 217  func execIO(o *operation, submit func(o *operation) error) (int, error) {
 218  	fd := o.fd
 219  	// Notify runtime netpoll about starting IO.
 220  	err := fd.pd.prepare(int(o.mode), fd.isFile)
 221  	if err != nil {
 222  		return 0, err
 223  	}
 224  	// Start IO.
 225  	if !fd.isBlocking && o.o.HEvent == 0 && !fd.pollable() {
 226  		// If the handle is opened for overlapped IO but we can't
 227  		// use the runtime poller, then we need to use an
 228  		// event to wait for the IO to complete.
 229  		o.setEvent()
 230  	}
 231  	o.qty = 0
 232  	o.flags = 0
 233  	err = submit(o)
 234  	var waitErr error
 235  	// Blocking operations shouldn't return ERROR_IO_PENDING.
 236  	// Continue without waiting if that happens.
 237  	if !o.fd.isBlocking && (err == syscall.ERROR_IO_PENDING || (err == nil && !o.fd.skipSyncNotif)) {
 238  		// IO started asynchronously or completed synchronously but
 239  		// a sync notification is required. Wait for it to complete.
 240  		waitErr = waitIO(o)
 241  		if waitErr != nil {
 242  			// IO interrupted by "close" or "timeout".
 243  			cancelIO(o)
 244  			// We issued a cancellation request, but the IO operation may still succeeded
 245  			// before the cancellation request runs.
 246  		}
 247  		if fd.isFile {
 248  			err = windows.GetOverlappedResult(fd.Sysfd, &o.o, &o.qty, false)
 249  		} else {
 250  			err = windows.WSAGetOverlappedResult(fd.Sysfd, &o.o, &o.qty, false, &o.flags)
 251  		}
 252  	}
 253  	switch err {
 254  	case syscall.ERROR_OPERATION_ABORTED:
 255  		// ERROR_OPERATION_ABORTED may have been caused by us. In that case,
 256  		// map it to our own error. Don't do more than that, each submitted
 257  		// function may have its own meaning for each error.
 258  		if waitErr != nil {
 259  			// IO canceled by the poller while waiting for completion.
 260  			err = waitErr
 261  		} else if fd.kind == kindPipe && fd.closing() {
 262  			// Close uses CancelIoEx to interrupt concurrent I/O for pipes.
 263  			// If the fd is a pipe and the Write was interrupted by CancelIoEx,
 264  			// we assume it is interrupted by Close.
 265  			err = errClosing(fd.isFile)
 266  		}
 267  	case windows.ERROR_IO_INCOMPLETE:
 268  		// waitIO couldn't wait for the IO to complete.
 269  		if waitErr != nil {
 270  			// The wait error will be more informative.
 271  			err = waitErr
 272  		}
 273  	}
 274  	return int(o.qty), err
 275  }
 276  
 277  // FD is a file descriptor. The net and os packages embed this type in
 278  // a larger type representing a network connection or OS file.
 279  type FD struct {
 280  	// Lock sysfd and serialize access to Read and Write methods.
 281  	fdmu fdMutex
 282  
 283  	// System file descriptor. Immutable until Close.
 284  	Sysfd syscall.Handle
 285  
 286  	// Read operation.
 287  	rop operation
 288  	// Write operation.
 289  	wop operation
 290  
 291  	// I/O poller.
 292  	pd pollDesc
 293  
 294  	// Used to implement pread/pwrite.
 295  	l sync.Mutex
 296  
 297  	// The file offset for the next read or write.
 298  	// Overlapped IO operations don't use the real file pointer,
 299  	// so we need to keep track of the offset ourselves.
 300  	offset int64
 301  
 302  	// For console I/O.
 303  	lastbits       []byte   // first few bytes of the last incomplete rune in last write
 304  	readuint16     []uint16 // buffer to hold uint16s obtained with ReadConsole
 305  	readbyte       []byte   // buffer to hold decoding of readuint16 from utf16 to utf8
 306  	readbyteOffset int      // readbyte[readOffset:] is yet to be consumed with file.Read
 307  
 308  	// Semaphore signaled when file is closed.
 309  	csema uint32
 310  
 311  	skipSyncNotif bool
 312  
 313  	// Whether this is a streaming descriptor, as opposed to a
 314  	// packet-based descriptor like a UDP socket.
 315  	IsStream bool
 316  
 317  	// Whether a zero byte read indicates EOF. This is false for a
 318  	// message based socket connection.
 319  	ZeroReadIsEOF bool
 320  
 321  	// Whether the handle is owned by os.File.
 322  	isFile bool
 323  
 324  	// The kind of this file.
 325  	kind fileKind
 326  
 327  	// Whether FILE_FLAG_OVERLAPPED was not set when opening the file.
 328  	isBlocking bool
 329  
 330  	disassociated atomic.Bool
 331  }
 332  
 333  // setOffset sets the offset fields of the overlapped object
 334  // to the given offset. The fd.l lock must be held.
 335  //
 336  // Overlapped IO operations don't update the offset fields
 337  // of the overlapped object nor the file pointer automatically,
 338  // so we do that manually here.
 339  // Note that this is a best effort that only works if the file
 340  // pointer is completely owned by this operation. We could
 341  // call seek to allow other processes or other operations on the
 342  // same file to see the updated offset. That would be inefficient
 343  // and won't work for concurrent operations anyway. If concurrent
 344  // operations are needed, then the caller should serialize them
 345  // using an external mechanism.
 346  func (fd *FD) setOffset(off int64) {
 347  	fd.offset = off
 348  	fd.rop.o.OffsetHigh, fd.rop.o.Offset = uint32(off>>32), uint32(off)
 349  	fd.wop.o.OffsetHigh, fd.wop.o.Offset = uint32(off>>32), uint32(off)
 350  }
 351  
 352  // addOffset adds the given offset to the current offset.
 353  func (fd *FD) addOffset(off int) {
 354  	fd.setOffset(fd.offset + int64(off))
 355  }
 356  
 357  // pollable should be used instead of fd.pd.pollable(),
 358  // as it is aware of the disassociated state.
 359  func (fd *FD) pollable() bool {
 360  	return fd.pd.pollable() && !fd.disassociated.Load()
 361  }
 362  
 363  // fileKind describes the kind of file.
 364  type fileKind byte
 365  
 366  const (
 367  	kindNet fileKind = iota
 368  	kindFile
 369  	kindConsole
 370  	kindPipe
 371  	kindFileNet
 372  )
 373  
 374  // Init initializes the FD. The Sysfd field should already be set.
 375  // This can be called multiple times on a single FD.
 376  // The net argument is a network name from the net package (e.g., "tcp"),
 377  // or "file" or "console" or "dir".
 378  // Set pollable to true if fd should be managed by runtime netpoll.
 379  // Pollable must be set to true for overlapped fds.
 380  func (fd *FD) Init(net []byte, pollable bool) error {
 381  	if initErr != nil {
 382  		return initErr
 383  	}
 384  
 385  	switch net {
 386  	case "file":
 387  		fd.kind = kindFile
 388  	case "console":
 389  		fd.kind = kindConsole
 390  	case "pipe":
 391  		fd.kind = kindPipe
 392  	case "file+net":
 393  		fd.kind = kindFileNet
 394  	default:
 395  		// We don't actually care about the various network types.
 396  		fd.kind = kindNet
 397  	}
 398  	fd.isFile = fd.kind != kindNet
 399  	fd.isBlocking = !pollable
 400  	fd.rop.mode = 'r'
 401  	fd.wop.mode = 'w'
 402  	fd.rop.fd = fd
 403  	fd.wop.fd = fd
 404  
 405  	// It is safe to add overlapped handles that also perform I/O
 406  	// outside of the runtime poller. The runtime poller will ignore
 407  	// I/O completion notifications not initiated by us.
 408  	err := fd.pd.init(fd)
 409  	if err != nil {
 410  		return err
 411  	}
 412  	fd.rop.runtimeCtx = fd.pd.runtimeCtx
 413  	fd.wop.runtimeCtx = fd.pd.runtimeCtx
 414  	if fd.kind != kindNet || socketCanUseSetFileCompletionNotificationModes {
 415  		// Non-socket handles can use SetFileCompletionNotificationModes without problems.
 416  		err := syscall.SetFileCompletionNotificationModes(fd.Sysfd,
 417  			syscall.FILE_SKIP_SET_EVENT_ON_HANDLE|syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS,
 418  		)
 419  		fd.skipSyncNotif = err == nil
 420  	}
 421  	return nil
 422  }
 423  
 424  // DisassociateIOCP disassociates the file handle from the IOCP.
 425  // The disassociate operation will not succeed if there is any
 426  // in-progress IO operation on the file handle.
 427  func (fd *FD) DisassociateIOCP() error {
 428  	if err := fd.incref(); err != nil {
 429  		return err
 430  	}
 431  	defer fd.decref()
 432  
 433  	if fd.isBlocking || !fd.pollable() {
 434  		// Nothing to disassociate.
 435  		return nil
 436  	}
 437  
 438  	info := windows.FILE_COMPLETION_INFORMATION{}
 439  	if err := windows.NtSetInformationFile(fd.Sysfd, &windows.IO_STATUS_BLOCK{}, unsafe.Pointer(&info), uint32(unsafe.Sizeof(info)), windows.FileReplaceCompletionInformation); err != nil {
 440  		return err
 441  	}
 442  	fd.disassociated.Store(true)
 443  	// Don't call fd.pd.close(), it would be too racy.
 444  	// There is no harm on leaving fd.pd open until Close is called.
 445  	return nil
 446  }
 447  
 448  func (fd *FD) destroy() error {
 449  	if fd.Sysfd == syscall.InvalidHandle {
 450  		return syscall.EINVAL
 451  	}
 452  	fd.rop.close()
 453  	fd.wop.close()
 454  	// Poller may want to unregister fd in readiness notification mechanism,
 455  	// so this must be executed before fd.CloseFunc.
 456  	fd.pd.close()
 457  	var err error
 458  	switch fd.kind {
 459  	case kindNet, kindFileNet:
 460  		// The net package uses the CloseFunc variable for testing.
 461  		err = CloseFunc(fd.Sysfd)
 462  	default:
 463  		err = syscall.CloseHandle(fd.Sysfd)
 464  	}
 465  	fd.Sysfd = syscall.InvalidHandle
 466  	runtime_Semrelease(&fd.csema)
 467  	return err
 468  }
 469  
 470  // Close closes the FD. The underlying file descriptor is closed by
 471  // the destroy method when there are no remaining references.
 472  func (fd *FD) Close() error {
 473  	if !fd.fdmu.increfAndClose() {
 474  		return errClosing(fd.isFile)
 475  	}
 476  
 477  	if fd.kind == kindPipe {
 478  		syscall.CancelIoEx(fd.Sysfd, nil)
 479  	}
 480  	// unblock pending reader and writer
 481  	fd.pd.evict()
 482  	err := fd.decref()
 483  	// Wait until the descriptor is closed. If this was the only
 484  	// reference, it is already closed.
 485  	runtime_Semacquire(&fd.csema)
 486  	return err
 487  }
 488  
 489  // Windows ReadFile and WSARecv use DWORD (uint32) parameter to pass buffer length.
 490  // This prevents us reading blocks larger than 4GB.
 491  // See golang.org/issue/26923.
 492  const maxRW = 1 << 30 // 1GB is large enough and keeps subsequent reads aligned
 493  
 494  // Read implements io.Reader.
 495  func (fd *FD) Read(buf []byte) (int, error) {
 496  	if err := fd.readLock(); err != nil {
 497  		return 0, err
 498  	}
 499  	defer fd.readUnlock()
 500  	if fd.kind == kindFile {
 501  		fd.l.Lock()
 502  		defer fd.l.Unlock()
 503  	}
 504  
 505  	if len(buf) > maxRW {
 506  		buf = buf[:maxRW]
 507  	}
 508  
 509  	var n int
 510  	var err error
 511  	switch fd.kind {
 512  	case kindConsole:
 513  		n, err = fd.readConsole(buf)
 514  	case kindFile, kindPipe:
 515  		o := &fd.rop
 516  		o.InitBuf(buf)
 517  		n, err = execIO(o, func(o *operation) error {
 518  			return syscall.ReadFile(o.fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &o.qty, o.overlapped())
 519  		})
 520  		fd.addOffset(n)
 521  		switch err {
 522  		case syscall.ERROR_HANDLE_EOF:
 523  			err = io.EOF
 524  		case syscall.ERROR_BROKEN_PIPE:
 525  			// ReadFile only documents ERROR_BROKEN_PIPE for pipes.
 526  			if fd.kind == kindPipe {
 527  				err = io.EOF
 528  			}
 529  		}
 530  	case kindNet:
 531  		o := &fd.rop
 532  		o.InitBuf(buf)
 533  		n, err = execIO(o, func(o *operation) error {
 534  			return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
 535  		})
 536  		if race.Enabled {
 537  			race.Acquire(unsafe.Pointer(&ioSync))
 538  		}
 539  	}
 540  	if len(buf) != 0 {
 541  		err = fd.eofError(n, err)
 542  	}
 543  	return n, err
 544  }
 545  
 546  var ReadConsole = syscall.ReadConsole // changed for testing
 547  
 548  // readConsole reads utf16 characters from console File,
 549  // encodes them into utf8 and stores them in buffer b.
 550  // It returns the number of utf8 bytes read and an error, if any.
 551  func (fd *FD) readConsole(b []byte) (int, error) {
 552  	if len(b) == 0 {
 553  		return 0, nil
 554  	}
 555  
 556  	if fd.readuint16 == nil {
 557  		// Note: syscall.ReadConsole fails for very large buffers.
 558  		// The limit is somewhere around (but not exactly) 16384.
 559  		// Stay well below.
 560  		fd.readuint16 = []uint16{:0:10000}
 561  		fd.readbyte = []byte{:0:4*cap(fd.readuint16)}
 562  	}
 563  
 564  	for fd.readbyteOffset >= len(fd.readbyte) {
 565  		n := cap(fd.readuint16) - len(fd.readuint16)
 566  		if n > len(b) {
 567  			n = len(b)
 568  		}
 569  		var nw uint32
 570  		err := ReadConsole(fd.Sysfd, &fd.readuint16[:len(fd.readuint16)+1][len(fd.readuint16)], uint32(n), &nw, nil)
 571  		if err != nil {
 572  			return 0, err
 573  		}
 574  		uint16s := fd.readuint16[:len(fd.readuint16)+int(nw)]
 575  		fd.readuint16 = fd.readuint16[:0]
 576  		buf := fd.readbyte[:0]
 577  		for i := 0; i < len(uint16s); i++ {
 578  			r := rune(uint16s[i])
 579  			if utf16.IsSurrogate(r) {
 580  				if i+1 == len(uint16s) {
 581  					if nw > 0 {
 582  						// Save half surrogate pair for next time.
 583  						fd.readuint16 = fd.readuint16[:1]
 584  						fd.readuint16[0] = uint16(r)
 585  						break
 586  					}
 587  					r = utf8.RuneError
 588  				} else {
 589  					r = utf16.DecodeRune(r, rune(uint16s[i+1]))
 590  					if r != utf8.RuneError {
 591  						i++
 592  					}
 593  				}
 594  			}
 595  			buf = utf8.AppendRune(buf, r)
 596  		}
 597  		fd.readbyte = buf
 598  		fd.readbyteOffset = 0
 599  		if nw == 0 {
 600  			break
 601  		}
 602  	}
 603  
 604  	src := fd.readbyte[fd.readbyteOffset:]
 605  	var i int
 606  	for i = 0; i < len(src) && i < len(b); i++ {
 607  		x := src[i]
 608  		if x == 0x1A { // Ctrl-Z
 609  			if i == 0 {
 610  				fd.readbyteOffset++
 611  			}
 612  			break
 613  		}
 614  		b[i] = x
 615  	}
 616  	fd.readbyteOffset += i
 617  	return i, nil
 618  }
 619  
 620  // Pread emulates the Unix pread system call.
 621  func (fd *FD) Pread(b []byte, off int64) (int, error) {
 622  	if fd.kind == kindPipe {
 623  		// Pread does not work with pipes
 624  		return 0, syscall.ESPIPE
 625  	}
 626  	// Call incref, not readLock, because since pread specifies the
 627  	// offset it is independent from other reads.
 628  	if err := fd.incref(); err != nil {
 629  		return 0, err
 630  	}
 631  	defer fd.decref()
 632  
 633  	if len(b) > maxRW {
 634  		b = b[:maxRW]
 635  	}
 636  
 637  	fd.l.Lock()
 638  	defer fd.l.Unlock()
 639  	if fd.isBlocking {
 640  		curoffset, err := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent)
 641  		if err != nil {
 642  			return 0, err
 643  		}
 644  		defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart)
 645  		defer fd.setOffset(curoffset)
 646  	} else {
 647  		// Overlapped handles don't have the file pointer updated
 648  		// when performing I/O operations, so there is no need to
 649  		// call Seek to reset the file pointer.
 650  		// Also, some overlapped file handles don't support seeking.
 651  		// See https://go.dev/issues/74951.
 652  		curoffset := fd.offset
 653  		defer fd.setOffset(curoffset)
 654  	}
 655  	o := &fd.rop
 656  	o.InitBuf(b)
 657  	fd.setOffset(off)
 658  	n, err := execIO(o, func(o *operation) error {
 659  		return syscall.ReadFile(o.fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &o.qty, &o.o)
 660  	})
 661  	if err == syscall.ERROR_HANDLE_EOF {
 662  		err = io.EOF
 663  	}
 664  	if len(b) != 0 {
 665  		err = fd.eofError(n, err)
 666  	}
 667  	return n, err
 668  }
 669  
 670  // ReadFrom wraps the recvfrom network call.
 671  func (fd *FD) ReadFrom(buf []byte) (int, syscall.Sockaddr, error) {
 672  	if len(buf) == 0 {
 673  		return 0, nil, nil
 674  	}
 675  	if len(buf) > maxRW {
 676  		buf = buf[:maxRW]
 677  	}
 678  	if err := fd.readLock(); err != nil {
 679  		return 0, nil, err
 680  	}
 681  	defer fd.readUnlock()
 682  	o := &fd.rop
 683  	o.InitBuf(buf)
 684  	n, err := execIO(o, func(o *operation) error {
 685  		if o.rsa == nil {
 686  			o.rsa = &syscall.RawSockaddrAny{}
 687  		}
 688  		o.rsan = int32(unsafe.Sizeof(*o.rsa))
 689  		return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
 690  	})
 691  	err = fd.eofError(n, err)
 692  	if err != nil {
 693  		return n, nil, err
 694  	}
 695  	sa, _ := o.rsa.Sockaddr()
 696  	return n, sa, nil
 697  }
 698  
 699  // ReadFromInet4 wraps the recvfrom network call for IPv4.
 700  func (fd *FD) ReadFromInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) {
 701  	if len(buf) == 0 {
 702  		return 0, nil
 703  	}
 704  	if len(buf) > maxRW {
 705  		buf = buf[:maxRW]
 706  	}
 707  	if err := fd.readLock(); err != nil {
 708  		return 0, err
 709  	}
 710  	defer fd.readUnlock()
 711  	o := &fd.rop
 712  	o.InitBuf(buf)
 713  	n, err := execIO(o, func(o *operation) error {
 714  		if o.rsa == nil {
 715  			o.rsa = &syscall.RawSockaddrAny{}
 716  		}
 717  		o.rsan = int32(unsafe.Sizeof(*o.rsa))
 718  		return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
 719  	})
 720  	err = fd.eofError(n, err)
 721  	if err != nil {
 722  		return n, err
 723  	}
 724  	rawToSockaddrInet4(o.rsa, sa4)
 725  	return n, err
 726  }
 727  
 728  // ReadFromInet6 wraps the recvfrom network call for IPv6.
 729  func (fd *FD) ReadFromInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) {
 730  	if len(buf) == 0 {
 731  		return 0, nil
 732  	}
 733  	if len(buf) > maxRW {
 734  		buf = buf[:maxRW]
 735  	}
 736  	if err := fd.readLock(); err != nil {
 737  		return 0, err
 738  	}
 739  	defer fd.readUnlock()
 740  	o := &fd.rop
 741  	o.InitBuf(buf)
 742  	n, err := execIO(o, func(o *operation) error {
 743  		if o.rsa == nil {
 744  			o.rsa = &syscall.RawSockaddrAny{}
 745  		}
 746  		o.rsan = int32(unsafe.Sizeof(*o.rsa))
 747  		return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
 748  	})
 749  	err = fd.eofError(n, err)
 750  	if err != nil {
 751  		return n, err
 752  	}
 753  	rawToSockaddrInet6(o.rsa, sa6)
 754  	return n, err
 755  }
 756  
 757  // Write implements io.Writer.
 758  func (fd *FD) Write(buf []byte) (int, error) {
 759  	if err := fd.writeLock(); err != nil {
 760  		return 0, err
 761  	}
 762  	defer fd.writeUnlock()
 763  	if fd.kind == kindFile {
 764  		fd.l.Lock()
 765  		defer fd.l.Unlock()
 766  	}
 767  
 768  	var ntotal int
 769  	for {
 770  		max := len(buf)
 771  		if max-ntotal > maxRW {
 772  			max = ntotal + maxRW
 773  		}
 774  		b := buf[ntotal:max]
 775  		var n int
 776  		var err error
 777  		switch fd.kind {
 778  		case kindConsole:
 779  			n, err = fd.writeConsole(b)
 780  		case kindPipe, kindFile:
 781  			o := &fd.wop
 782  			o.InitBuf(b)
 783  			n, err = execIO(o, func(o *operation) error {
 784  				return syscall.WriteFile(o.fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &o.qty, o.overlapped())
 785  			})
 786  			fd.addOffset(n)
 787  		case kindNet:
 788  			if race.Enabled {
 789  				race.ReleaseMerge(unsafe.Pointer(&ioSync))
 790  			}
 791  			o := &fd.wop
 792  			o.InitBuf(b)
 793  			n, err = execIO(o, func(o *operation) error {
 794  				return syscall.WSASend(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil)
 795  			})
 796  		}
 797  		ntotal += n
 798  		if ntotal == len(buf) || err != nil {
 799  			return ntotal, err
 800  		}
 801  		if n == 0 {
 802  			return ntotal, io.ErrUnexpectedEOF
 803  		}
 804  	}
 805  }
 806  
 807  // writeConsole writes len(b) bytes to the console File.
 808  // It returns the number of bytes written and an error, if any.
 809  func (fd *FD) writeConsole(b []byte) (int, error) {
 810  	n := len(b)
 811  	runes := []rune{:0:256}
 812  	if len(fd.lastbits) > 0 {
 813  		b = append(fd.lastbits, b...)
 814  		fd.lastbits = nil
 815  
 816  	}
 817  	for len(b) >= utf8.UTFMax || utf8.FullRune(b) {
 818  		r, l := utf8.DecodeRune(b)
 819  		runes = append(runes, r)
 820  		b = b[l:]
 821  	}
 822  	if len(b) > 0 {
 823  		fd.lastbits = []byte{:len(b)}
 824  		copy(fd.lastbits, b)
 825  	}
 826  	// syscall.WriteConsole seems to fail, if given large buffer.
 827  	// So limit the buffer to 16000 characters. This number was
 828  	// discovered by experimenting with syscall.WriteConsole.
 829  	const maxWrite = 16000
 830  	for len(runes) > 0 {
 831  		m := len(runes)
 832  		if m > maxWrite {
 833  			m = maxWrite
 834  		}
 835  		chunk := runes[:m]
 836  		runes = runes[m:]
 837  		uint16s := utf16.Encode(chunk)
 838  		for len(uint16s) > 0 {
 839  			var written uint32
 840  			err := syscall.WriteConsole(fd.Sysfd, &uint16s[0], uint32(len(uint16s)), &written, nil)
 841  			if err != nil {
 842  				return 0, err
 843  			}
 844  			uint16s = uint16s[written:]
 845  		}
 846  	}
 847  	return n, nil
 848  }
 849  
 850  // Pwrite emulates the Unix pwrite system call.
 851  func (fd *FD) Pwrite(buf []byte, off int64) (int, error) {
 852  	if fd.kind == kindPipe {
 853  		// Pwrite does not work with pipes
 854  		return 0, syscall.ESPIPE
 855  	}
 856  	// Call incref, not writeLock, because since pwrite specifies the
 857  	// offset it is independent from other writes.
 858  	if err := fd.incref(); err != nil {
 859  		return 0, err
 860  	}
 861  	defer fd.decref()
 862  
 863  	fd.l.Lock()
 864  	defer fd.l.Unlock()
 865  	if fd.isBlocking {
 866  		curoffset, err := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent)
 867  		if err != nil {
 868  			return 0, err
 869  		}
 870  		defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart)
 871  		defer fd.setOffset(curoffset)
 872  	} else {
 873  		// Overlapped handles don't have the file pointer updated
 874  		// when performing I/O operations, so there is no need to
 875  		// call Seek to reset the file pointer.
 876  		// Also, some overlapped file handles don't support seeking.
 877  		// See https://go.dev/issues/74951.
 878  		curoffset := fd.offset
 879  		defer fd.setOffset(curoffset)
 880  	}
 881  
 882  	var ntotal int
 883  	for {
 884  		max := len(buf)
 885  		if max-ntotal > maxRW {
 886  			max = ntotal + maxRW
 887  		}
 888  		b := buf[ntotal:max]
 889  		o := &fd.wop
 890  		o.InitBuf(b)
 891  		fd.setOffset(off + int64(ntotal))
 892  		n, err := execIO(o, func(o *operation) error {
 893  			return syscall.WriteFile(o.fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &o.qty, &o.o)
 894  		})
 895  		if n > 0 {
 896  			ntotal += n
 897  		}
 898  		if ntotal == len(buf) || err != nil {
 899  			return ntotal, err
 900  		}
 901  		if n == 0 {
 902  			return ntotal, io.ErrUnexpectedEOF
 903  		}
 904  	}
 905  }
 906  
 907  // Writev emulates the Unix writev system call.
 908  func (fd *FD) Writev(buf *[][]byte) (int64, error) {
 909  	if len(*buf) == 0 {
 910  		return 0, nil
 911  	}
 912  	if err := fd.writeLock(); err != nil {
 913  		return 0, err
 914  	}
 915  	defer fd.writeUnlock()
 916  	if race.Enabled {
 917  		race.ReleaseMerge(unsafe.Pointer(&ioSync))
 918  	}
 919  	o := &fd.wop
 920  	o.InitBufs(buf)
 921  	n, err := execIO(o, func(o *operation) error {
 922  		return syscall.WSASend(o.fd.Sysfd, &o.bufs[0], uint32(len(o.bufs)), &o.qty, 0, &o.o, nil)
 923  	})
 924  	o.ClearBufs()
 925  	TestHookDidWritev(n)
 926  	consume(buf, int64(n))
 927  	return int64(n), err
 928  }
 929  
 930  // WriteTo wraps the sendto network call.
 931  func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) {
 932  	if err := fd.writeLock(); err != nil {
 933  		return 0, err
 934  	}
 935  	defer fd.writeUnlock()
 936  
 937  	if len(buf) == 0 {
 938  		// handle zero-byte payload
 939  		o := &fd.wop
 940  		o.InitBuf(buf)
 941  		o.sa = sa
 942  		n, err := execIO(o, func(o *operation) error {
 943  			return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
 944  		})
 945  		return n, err
 946  	}
 947  
 948  	ntotal := 0
 949  	for len(buf) > 0 {
 950  		b := buf
 951  		if len(b) > maxRW {
 952  			b = b[:maxRW]
 953  		}
 954  		o := &fd.wop
 955  		o.InitBuf(b)
 956  		o.sa = sa
 957  		n, err := execIO(o, func(o *operation) error {
 958  			return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
 959  		})
 960  		ntotal += int(n)
 961  		if err != nil {
 962  			return ntotal, err
 963  		}
 964  		buf = buf[n:]
 965  	}
 966  	return ntotal, nil
 967  }
 968  
 969  // WriteToInet4 is WriteTo, specialized for syscall.SockaddrInet4.
 970  func (fd *FD) WriteToInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) {
 971  	if err := fd.writeLock(); err != nil {
 972  		return 0, err
 973  	}
 974  	defer fd.writeUnlock()
 975  
 976  	if len(buf) == 0 {
 977  		// handle zero-byte payload
 978  		o := &fd.wop
 979  		o.InitBuf(buf)
 980  		n, err := execIO(o, func(o *operation) error {
 981  			return windows.WSASendtoInet4(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa4, &o.o, nil)
 982  		})
 983  		return n, err
 984  	}
 985  
 986  	ntotal := 0
 987  	for len(buf) > 0 {
 988  		b := buf
 989  		if len(b) > maxRW {
 990  			b = b[:maxRW]
 991  		}
 992  		o := &fd.wop
 993  		o.InitBuf(b)
 994  		n, err := execIO(o, func(o *operation) error {
 995  			return windows.WSASendtoInet4(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa4, &o.o, nil)
 996  		})
 997  		ntotal += int(n)
 998  		if err != nil {
 999  			return ntotal, err
1000  		}
1001  		buf = buf[n:]
1002  	}
1003  	return ntotal, nil
1004  }
1005  
1006  // WriteToInet6 is WriteTo, specialized for syscall.SockaddrInet6.
1007  func (fd *FD) WriteToInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) {
1008  	if err := fd.writeLock(); err != nil {
1009  		return 0, err
1010  	}
1011  	defer fd.writeUnlock()
1012  
1013  	if len(buf) == 0 {
1014  		// handle zero-byte payload
1015  		o := &fd.wop
1016  		o.InitBuf(buf)
1017  		n, err := execIO(o, func(o *operation) error {
1018  			return windows.WSASendtoInet6(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa6, &o.o, nil)
1019  		})
1020  		return n, err
1021  	}
1022  
1023  	ntotal := 0
1024  	for len(buf) > 0 {
1025  		b := buf
1026  		if len(b) > maxRW {
1027  			b = b[:maxRW]
1028  		}
1029  		o := &fd.wop
1030  		o.InitBuf(b)
1031  		n, err := execIO(o, func(o *operation) error {
1032  			return windows.WSASendtoInet6(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa6, &o.o, nil)
1033  		})
1034  		ntotal += int(n)
1035  		if err != nil {
1036  			return ntotal, err
1037  		}
1038  		buf = buf[n:]
1039  	}
1040  	return ntotal, nil
1041  }
1042  
1043  // Call ConnectEx. This doesn't need any locking, since it is only
1044  // called when the descriptor is first created. This is here rather
1045  // than in the net package so that it can use fd.wop.
1046  func (fd *FD) ConnectEx(ra syscall.Sockaddr) error {
1047  	o := &fd.wop
1048  	o.sa = ra
1049  	_, err := execIO(o, func(o *operation) error {
1050  		return ConnectExFunc(o.fd.Sysfd, o.sa, nil, 0, nil, &o.o)
1051  	})
1052  	return err
1053  }
1054  
1055  func (fd *FD) acceptOne(s syscall.Handle, rawsa []syscall.RawSockaddrAny, o *operation) ([]byte, error) {
1056  	// Submit accept request.
1057  	o.handle = s
1058  	o.rsan = int32(unsafe.Sizeof(rawsa[0]))
1059  	_, err := execIO(o, func(o *operation) error {
1060  		return AcceptFunc(o.fd.Sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o)
1061  	})
1062  	if err != nil {
1063  		CloseFunc(s)
1064  		return "acceptex", err
1065  	}
1066  
1067  	// Inherit properties of the listening socket.
1068  	err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.Sysfd)), int32(unsafe.Sizeof(fd.Sysfd)))
1069  	if err != nil {
1070  		CloseFunc(s)
1071  		return "setsockopt", err
1072  	}
1073  
1074  	return "", nil
1075  }
1076  
1077  // Accept handles accepting a socket. The sysSocket parameter is used
1078  // to allocate the net socket.
1079  func (fd *FD) Accept(sysSocket func() (syscall.Handle, error)) (syscall.Handle, []syscall.RawSockaddrAny, uint32, []byte, error) {
1080  	if err := fd.readLock(); err != nil {
1081  		return syscall.InvalidHandle, nil, 0, "", err
1082  	}
1083  	defer fd.readUnlock()
1084  
1085  	o := &fd.rop
1086  	var rawsa [2]syscall.RawSockaddrAny
1087  	for {
1088  		s, err := sysSocket()
1089  		if err != nil {
1090  			return syscall.InvalidHandle, nil, 0, "", err
1091  		}
1092  
1093  		errcall, err := fd.acceptOne(s, rawsa[:], o)
1094  		if err == nil {
1095  			return s, rawsa[:], uint32(o.rsan), "", nil
1096  		}
1097  
1098  		// Sometimes we see WSAECONNRESET and ERROR_NETNAME_DELETED is
1099  		// returned here. These happen if connection reset is received
1100  		// before AcceptEx could complete. These errors relate to new
1101  		// connection, not to AcceptEx, so ignore broken connection and
1102  		// try AcceptEx again for more connections.
1103  		errno, ok := err.(syscall.Errno)
1104  		if !ok {
1105  			return syscall.InvalidHandle, nil, 0, errcall, err
1106  		}
1107  		switch errno {
1108  		case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET:
1109  			// ignore these and try again
1110  		default:
1111  			return syscall.InvalidHandle, nil, 0, errcall, err
1112  		}
1113  	}
1114  }
1115  
1116  // Seek wraps syscall.Seek.
1117  func (fd *FD) Seek(offset int64, whence int) (int64, error) {
1118  	if fd.kind == kindPipe {
1119  		return 0, syscall.ESPIPE
1120  	}
1121  	if err := fd.incref(); err != nil {
1122  		return 0, err
1123  	}
1124  	defer fd.decref()
1125  
1126  	fd.l.Lock()
1127  	defer fd.l.Unlock()
1128  
1129  	if !fd.isBlocking && whence == io.SeekCurrent {
1130  		// Windows doesn't keep the file pointer for overlapped file handles.
1131  		// We do it ourselves in case to account for any read or write
1132  		// operations that may have occurred.
1133  		offset += fd.offset
1134  	}
1135  	n, err := syscall.Seek(fd.Sysfd, offset, whence)
1136  	fd.setOffset(n)
1137  	return n, err
1138  }
1139  
1140  // Fchmod updates syscall.ByHandleFileInformation.Fileattributes when needed.
1141  func (fd *FD) Fchmod(mode uint32) error {
1142  	if err := fd.incref(); err != nil {
1143  		return err
1144  	}
1145  	defer fd.decref()
1146  
1147  	var d syscall.ByHandleFileInformation
1148  	if err := syscall.GetFileInformationByHandle(fd.Sysfd, &d); err != nil {
1149  		return err
1150  	}
1151  	attrs := d.FileAttributes
1152  	if mode&syscall.S_IWRITE != 0 {
1153  		attrs &^= syscall.FILE_ATTRIBUTE_READONLY
1154  	} else {
1155  		attrs |= syscall.FILE_ATTRIBUTE_READONLY
1156  	}
1157  	if attrs == d.FileAttributes {
1158  		return nil
1159  	}
1160  
1161  	var du windows.FILE_BASIC_INFO
1162  	du.FileAttributes = attrs
1163  	return windows.SetFileInformationByHandle(fd.Sysfd, windows.FileBasicInfo, unsafe.Pointer(&du), uint32(unsafe.Sizeof(du)))
1164  }
1165  
1166  // Fchdir wraps syscall.Fchdir.
1167  func (fd *FD) Fchdir() error {
1168  	if err := fd.incref(); err != nil {
1169  		return err
1170  	}
1171  	defer fd.decref()
1172  	return syscall.Fchdir(fd.Sysfd)
1173  }
1174  
1175  // GetFileType wraps syscall.GetFileType.
1176  func (fd *FD) GetFileType() (uint32, error) {
1177  	if err := fd.incref(); err != nil {
1178  		return 0, err
1179  	}
1180  	defer fd.decref()
1181  	return syscall.GetFileType(fd.Sysfd)
1182  }
1183  
1184  // GetFileInformationByHandle wraps GetFileInformationByHandle.
1185  func (fd *FD) GetFileInformationByHandle(data *syscall.ByHandleFileInformation) error {
1186  	if err := fd.incref(); err != nil {
1187  		return err
1188  	}
1189  	defer fd.decref()
1190  	return syscall.GetFileInformationByHandle(fd.Sysfd, data)
1191  }
1192  
1193  // RawRead invokes the user-defined function f for a read operation.
1194  func (fd *FD) RawRead(f func(uintptr) bool) error {
1195  	if err := fd.readLock(); err != nil {
1196  		return err
1197  	}
1198  	defer fd.readUnlock()
1199  	for {
1200  		if f(uintptr(fd.Sysfd)) {
1201  			return nil
1202  		}
1203  
1204  		// Use a zero-byte read as a way to get notified when this
1205  		// socket is readable. h/t https://stackoverflow.com/a/42019668/332798
1206  		o := &fd.rop
1207  		o.InitBuf(nil)
1208  		_, err := execIO(o, func(o *operation) error {
1209  			if !fd.IsStream {
1210  				o.flags |= windows.MSG_PEEK
1211  			}
1212  			return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
1213  		})
1214  		if err == windows.WSAEMSGSIZE {
1215  			// expected with a 0-byte peek, ignore.
1216  		} else if err != nil {
1217  			return err
1218  		}
1219  	}
1220  }
1221  
1222  // RawWrite invokes the user-defined function f for a write operation.
1223  func (fd *FD) RawWrite(f func(uintptr) bool) error {
1224  	if err := fd.writeLock(); err != nil {
1225  		return err
1226  	}
1227  	defer fd.writeUnlock()
1228  
1229  	if f(uintptr(fd.Sysfd)) {
1230  		return nil
1231  	}
1232  
1233  	// TODO(tmm1): find a way to detect socket writability
1234  	return syscall.EWINDOWS
1235  }
1236  
1237  func sockaddrInet4ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) int32 {
1238  	*rsa = syscall.RawSockaddrAny{}
1239  	raw := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
1240  	raw.Family = syscall.AF_INET
1241  	p := (*[2]byte)(unsafe.Pointer(&raw.Port))
1242  	p[0] = byte(sa.Port >> 8)
1243  	p[1] = byte(sa.Port)
1244  	raw.Addr = sa.Addr
1245  	return int32(unsafe.Sizeof(*raw))
1246  }
1247  
1248  func sockaddrInet6ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) int32 {
1249  	*rsa = syscall.RawSockaddrAny{}
1250  	raw := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
1251  	raw.Family = syscall.AF_INET6
1252  	p := (*[2]byte)(unsafe.Pointer(&raw.Port))
1253  	p[0] = byte(sa.Port >> 8)
1254  	p[1] = byte(sa.Port)
1255  	raw.Scope_id = sa.ZoneId
1256  	raw.Addr = sa.Addr
1257  	return int32(unsafe.Sizeof(*raw))
1258  }
1259  
1260  func rawToSockaddrInet4(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) {
1261  	pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
1262  	p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1263  	sa.Port = int(p[0])<<8 + int(p[1])
1264  	sa.Addr = pp.Addr
1265  }
1266  
1267  func rawToSockaddrInet6(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) {
1268  	pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
1269  	p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1270  	sa.Port = int(p[0])<<8 + int(p[1])
1271  	sa.ZoneId = pp.Scope_id
1272  	sa.Addr = pp.Addr
1273  }
1274  
1275  func sockaddrToRaw(rsa *syscall.RawSockaddrAny, sa syscall.Sockaddr) (int32, error) {
1276  	switch sa := sa.(type) {
1277  	case *syscall.SockaddrInet4:
1278  		sz := sockaddrInet4ToRaw(rsa, sa)
1279  		return sz, nil
1280  	case *syscall.SockaddrInet6:
1281  		sz := sockaddrInet6ToRaw(rsa, sa)
1282  		return sz, nil
1283  	default:
1284  		return 0, syscall.EWINDOWS
1285  	}
1286  }
1287  
1288  // ReadMsg wraps the WSARecvMsg network call.
1289  func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.Sockaddr, error) {
1290  	if err := fd.readLock(); err != nil {
1291  		return 0, 0, 0, nil, err
1292  	}
1293  	defer fd.readUnlock()
1294  
1295  	if len(p) > maxRW {
1296  		p = p[:maxRW]
1297  	}
1298  
1299  	o := &fd.rop
1300  	o.InitMsg(p, oob)
1301  	if o.rsa == nil {
1302  		o.rsa = &syscall.RawSockaddrAny{}
1303  	}
1304  	o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1305  	o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
1306  	o.msg.Flags = uint32(flags)
1307  	n, err := execIO(o, func(o *operation) error {
1308  		return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
1309  	})
1310  	err = fd.eofError(n, err)
1311  	var sa syscall.Sockaddr
1312  	if err == nil {
1313  		sa, err = o.rsa.Sockaddr()
1314  	}
1315  	return n, int(o.msg.Control.Len), int(o.msg.Flags), sa, err
1316  }
1317  
1318  // ReadMsgInet4 is ReadMsg, but specialized to return a syscall.SockaddrInet4.
1319  func (fd *FD) ReadMsgInet4(p []byte, oob []byte, flags int, sa4 *syscall.SockaddrInet4) (int, int, int, error) {
1320  	if err := fd.readLock(); err != nil {
1321  		return 0, 0, 0, err
1322  	}
1323  	defer fd.readUnlock()
1324  
1325  	if len(p) > maxRW {
1326  		p = p[:maxRW]
1327  	}
1328  
1329  	o := &fd.rop
1330  	o.InitMsg(p, oob)
1331  	if o.rsa == nil {
1332  		o.rsa = &syscall.RawSockaddrAny{}
1333  	}
1334  	o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1335  	o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
1336  	o.msg.Flags = uint32(flags)
1337  	n, err := execIO(o, func(o *operation) error {
1338  		return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
1339  	})
1340  	err = fd.eofError(n, err)
1341  	if err == nil {
1342  		rawToSockaddrInet4(o.rsa, sa4)
1343  	}
1344  	return n, int(o.msg.Control.Len), int(o.msg.Flags), err
1345  }
1346  
1347  // ReadMsgInet6 is ReadMsg, but specialized to return a syscall.SockaddrInet6.
1348  func (fd *FD) ReadMsgInet6(p []byte, oob []byte, flags int, sa6 *syscall.SockaddrInet6) (int, int, int, error) {
1349  	if err := fd.readLock(); err != nil {
1350  		return 0, 0, 0, err
1351  	}
1352  	defer fd.readUnlock()
1353  
1354  	if len(p) > maxRW {
1355  		p = p[:maxRW]
1356  	}
1357  
1358  	o := &fd.rop
1359  	o.InitMsg(p, oob)
1360  	if o.rsa == nil {
1361  		o.rsa = &syscall.RawSockaddrAny{}
1362  	}
1363  	o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1364  	o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
1365  	o.msg.Flags = uint32(flags)
1366  	n, err := execIO(o, func(o *operation) error {
1367  		return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
1368  	})
1369  	err = fd.eofError(n, err)
1370  	if err == nil {
1371  		rawToSockaddrInet6(o.rsa, sa6)
1372  	}
1373  	return n, int(o.msg.Control.Len), int(o.msg.Flags), err
1374  }
1375  
1376  // WriteMsg wraps the WSASendMsg network call.
1377  func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
1378  	if len(p) > maxRW {
1379  		return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1380  	}
1381  
1382  	if err := fd.writeLock(); err != nil {
1383  		return 0, 0, err
1384  	}
1385  	defer fd.writeUnlock()
1386  
1387  	o := &fd.wop
1388  	o.InitMsg(p, oob)
1389  	if sa != nil {
1390  		if o.rsa == nil {
1391  			o.rsa = &syscall.RawSockaddrAny{}
1392  		}
1393  		len, err := sockaddrToRaw(o.rsa, sa)
1394  		if err != nil {
1395  			return 0, 0, err
1396  		}
1397  		o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1398  		o.msg.Namelen = len
1399  	}
1400  	n, err := execIO(o, func(o *operation) error {
1401  		return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
1402  	})
1403  	return n, int(o.msg.Control.Len), err
1404  }
1405  
1406  // WriteMsgInet4 is WriteMsg specialized for syscall.SockaddrInet4.
1407  func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (int, int, error) {
1408  	if len(p) > maxRW {
1409  		return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1410  	}
1411  
1412  	if err := fd.writeLock(); err != nil {
1413  		return 0, 0, err
1414  	}
1415  	defer fd.writeUnlock()
1416  
1417  	o := &fd.wop
1418  	o.InitMsg(p, oob)
1419  	if o.rsa == nil {
1420  		o.rsa = &syscall.RawSockaddrAny{}
1421  	}
1422  	len := sockaddrInet4ToRaw(o.rsa, sa)
1423  	o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1424  	o.msg.Namelen = len
1425  	n, err := execIO(o, func(o *operation) error {
1426  		return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
1427  	})
1428  	return n, int(o.msg.Control.Len), err
1429  }
1430  
1431  // WriteMsgInet6 is WriteMsg specialized for syscall.SockaddrInet6.
1432  func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (int, int, error) {
1433  	if len(p) > maxRW {
1434  		return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1435  	}
1436  
1437  	if err := fd.writeLock(); err != nil {
1438  		return 0, 0, err
1439  	}
1440  	defer fd.writeUnlock()
1441  
1442  	o := &fd.wop
1443  	o.InitMsg(p, oob)
1444  	if o.rsa == nil {
1445  		o.rsa = &syscall.RawSockaddrAny{}
1446  	}
1447  	len := sockaddrInet6ToRaw(o.rsa, sa)
1448  	o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1449  	o.msg.Namelen = len
1450  	n, err := execIO(o, func(o *operation) error {
1451  		return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
1452  	})
1453  	return n, int(o.msg.Control.Len), err
1454  }
1455  
1456  func DupCloseOnExec(fd int) (int, []byte, error) {
1457  	proc, err := syscall.GetCurrentProcess()
1458  	if err != nil {
1459  		return 0, "GetCurrentProcess", err
1460  	}
1461  
1462  	var nfd syscall.Handle
1463  	const inherit = false // analogous to CLOEXEC
1464  	if err := syscall.DuplicateHandle(proc, syscall.Handle(fd), proc, &nfd, 0, inherit, syscall.DUPLICATE_SAME_ACCESS); err != nil {
1465  		return 0, "DuplicateHandle", err
1466  	}
1467  	return int(nfd), "", nil
1468  }
1469