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