github.com/AESNooper/go/src@v0.0.0-20220218095104-b56a4ab1bbbb/internal/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 "internal/race" 10 "internal/syscall/windows" 11 "io" 12 "sync" 13 "syscall" 14 "unicode/utf16" 15 "unicode/utf8" 16 "unsafe" 17 ) 18 19 var ( 20 initErr error 21 ioSync uint64 22 ) 23 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). 29 30 var useSetFileCompletionNotificationModes bool // determines is SetFileCompletionNotificationModes is present and safe to use 31 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() 38 if err != nil { 39 return 40 } 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) 45 if err != nil { 46 return 47 } 48 for i := int32(0); i < n; i++ { 49 if buf[i].ServiceFlags1&syscall.XP1_IFS_HANDLES == 0 { 50 return 51 } 52 } 53 useSetFileCompletionNotificationModes = true 54 } 55 56 func init() { 57 var d syscall.WSAData 58 e := syscall.WSAStartup(uint32(0x202), &d) 59 if e != nil { 60 initErr = e 61 } 62 checkSetFileCompletionNotificationModes() 63 } 64 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. 69 o syscall.Overlapped 70 71 // fields used by runtime.netpoll 72 runtimeCtx uintptr 73 mode int32 74 errno int32 75 qty uint32 76 77 // fields used only by net package 78 fd *FD 79 buf syscall.WSABuf 80 msg windows.WSAMsg 81 sa syscall.Sockaddr 82 rsa *syscall.RawSockaddrAny 83 rsan int32 84 handle syscall.Handle 85 flags uint32 86 bufs []syscall.WSABuf 87 } 88 89 func (o *operation) InitBuf(buf []byte) { 90 o.buf.Len = uint32(len(buf)) 91 o.buf.Buf = nil 92 if len(buf) != 0 { 93 o.buf.Buf = &buf[0] 94 } 95 } 96 97 func (o *operation) InitBufs(buf *[][]byte) { 98 if o.bufs == nil { 99 o.bufs = make([]syscall.WSABuf, 0, len(*buf)) 100 } else { 101 o.bufs = o.bufs[:0] 102 } 103 for _, b := range *buf { 104 if len(b) == 0 { 105 o.bufs = append(o.bufs, syscall.WSABuf{}) 106 continue 107 } 108 for len(b) > maxRW { 109 o.bufs = append(o.bufs, syscall.WSABuf{Len: maxRW, Buf: &b[0]}) 110 b = b[maxRW:] 111 } 112 if len(b) > 0 { 113 o.bufs = append(o.bufs, syscall.WSABuf{Len: uint32(len(b)), Buf: &b[0]}) 114 } 115 } 116 } 117 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 { 122 o.bufs[i].Buf = nil 123 } 124 o.bufs = o.bufs[:0] 125 } 126 127 func (o *operation) InitMsg(p []byte, oob []byte) { 128 o.InitBuf(p) 129 o.msg.Buffers = &o.buf 130 o.msg.BufferCount = 1 131 132 o.msg.Name = nil 133 o.msg.Namelen = 0 134 135 o.msg.Flags = 0 136 o.msg.Control.Len = uint32(len(oob)) 137 o.msg.Control.Buf = nil 138 if len(oob) != 0 { 139 o.msg.Control.Buf = &oob[0] 140 } 141 } 142 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") 150 } 151 152 fd := o.fd 153 // Notify runtime netpoll about starting IO. 154 err := fd.pd.prepare(int(o.mode), fd.isFile) 155 if err != nil { 156 return 0, err 157 } 158 // Start IO. 159 err = submit(o) 160 switch err { 161 case nil: 162 // IO completed immediately 163 if o.fd.skipSyncNotif { 164 // No completion message will follow, so return immediately. 165 return int(o.qty), nil 166 } 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. 170 err = nil 171 default: 172 return 0, err 173 } 174 // Wait for our request to complete. 175 err = fd.pd.wait(int(o.mode), fd.isFile) 176 if err == nil { 177 // All is good. Extract our IO results and return. 178 if o.errno != 0 { 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 183 } 184 return 0, err 185 } 186 return int(o.qty), nil 187 } 188 // IO is interrupted by "close" or "timeout" 189 netpollErr := err 190 switch netpollErr { 191 case ErrNetClosing, ErrFileClosing, ErrDeadlineExceeded: 192 // will deal with those. 193 default: 194 panic("unexpected runtime.netpoll error: " + netpollErr.Error()) 195 } 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. 201 panic(err) 202 } 203 // Wait for cancellation to complete. 204 fd.pd.waitCanceled(int(o.mode)) 205 if o.errno != 0 { 206 err = syscall.Errno(o.errno) 207 if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled 208 err = netpollErr 209 } 210 return 0, err 211 } 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 216 } 217 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. 220 type FD struct { 221 // Lock sysfd and serialize access to Read and Write methods. 222 fdmu fdMutex 223 224 // System file descriptor. Immutable until Close. 225 Sysfd syscall.Handle 226 227 // Read operation. 228 rop operation 229 // Write operation. 230 wop operation 231 232 // I/O poller. 233 pd pollDesc 234 235 // Used to implement pread/pwrite. 236 l sync.Mutex 237 238 // For console I/O. 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 243 244 // Semaphore signaled when file is closed. 245 csema uint32 246 247 skipSyncNotif bool 248 249 // Whether this is a streaming descriptor, as opposed to a 250 // packet-based descriptor like a UDP socket. 251 IsStream bool 252 253 // Whether a zero byte read indicates EOF. This is false for a 254 // message based socket connection. 255 ZeroReadIsEOF bool 256 257 // Whether this is a file rather than a network socket. 258 isFile bool 259 260 // The kind of this file. 261 kind fileKind 262 } 263 264 // fileKind describes the kind of file. 265 type fileKind byte 266 267 const ( 268 kindNet fileKind = iota 269 kindFile 270 kindConsole 271 kindDir 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": 290 fd.kind = kindFile 291 case "console": 292 fd.kind = kindConsole 293 case "dir": 294 fd.kind = kindDir 295 case "pipe": 296 fd.kind = kindPipe 297 case "tcp", "tcp4", "tcp6", 298 "udp", "udp4", "udp6", 299 "ip", "ip4", "ip6", 300 "unix", "unixgram", "unixpacket": 301 fd.kind = kindNet 302 default: 303 return "", errors.New("internal error: unknown network type " + net) 304 } 305 fd.isFile = fd.kind != kindNet 306 307 var err error 308 if pollable { 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. 313 // See issue #21172. 314 // 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. 320 err = fd.pd.init(fd) 321 } 322 if logInitFD != nil { 323 logInitFD(net, fd, err) 324 } 325 if err != nil { 326 return "", err 327 } 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 333 if net == "tcp" { 334 flags |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 335 } 336 err := syscall.SetFileCompletionNotificationModes(fd.Sysfd, flags) 337 if err == nil && flags&syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS != 0 { 338 fd.skipSyncNotif = true 339 } 340 } 341 // Disable SIO_UDP_CONNRESET behavior. 342 // http://support.microsoft.com/kb/263823 343 switch net { 344 case "udp", "udp4", "udp6": 345 ret := uint32(0) 346 flag := uint32(0) 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) 349 if err != nil { 350 return "wsaioctl", err 351 } 352 } 353 fd.rop.mode = 'r' 354 fd.wop.mode = 'w' 355 fd.rop.fd = fd 356 fd.wop.fd = fd 357 fd.rop.runtimeCtx = fd.pd.runtimeCtx 358 fd.wop.runtimeCtx = fd.pd.runtimeCtx 359 return "", nil 360 } 361 362 func (fd *FD) destroy() error { 363 if fd.Sysfd == syscall.InvalidHandle { 364 return syscall.EINVAL 365 } 366 // Poller may want to unregister fd in readiness notification mechanism, 367 // so this must be executed before fd.CloseFunc. 368 fd.pd.close() 369 var err error 370 switch fd.kind { 371 case kindNet: 372 // The net package uses the CloseFunc variable for testing. 373 err = CloseFunc(fd.Sysfd) 374 case kindDir: 375 err = syscall.FindClose(fd.Sysfd) 376 default: 377 err = syscall.CloseHandle(fd.Sysfd) 378 } 379 fd.Sysfd = syscall.InvalidHandle 380 runtime_Semrelease(&fd.csema) 381 return err 382 } 383 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) 389 } 390 if fd.kind == kindPipe { 391 syscall.CancelIoEx(fd.Sysfd, nil) 392 } 393 // unblock pending reader and writer 394 fd.pd.evict() 395 err := fd.decref() 396 // Wait until the descriptor is closed. If this was the only 397 // reference, it is already closed. 398 runtime_Semacquire(&fd.csema) 399 return err 400 } 401 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 406 407 // Read implements io.Reader. 408 func (fd *FD) Read(buf []byte) (int, error) { 409 if err := fd.readLock(); err != nil { 410 return 0, err 411 } 412 defer fd.readUnlock() 413 414 if len(buf) > maxRW { 415 buf = buf[:maxRW] 416 } 417 418 var n int 419 var err error 420 if fd.isFile { 421 fd.l.Lock() 422 defer fd.l.Unlock() 423 switch fd.kind { 424 case kindConsole: 425 n, err = fd.readConsole(buf) 426 default: 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. 432 err = ErrFileClosing 433 } 434 } 435 if err != nil { 436 n = 0 437 } 438 } else { 439 o := &fd.rop 440 o.InitBuf(buf) 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) 443 }) 444 if race.Enabled { 445 race.Acquire(unsafe.Pointer(&ioSync)) 446 } 447 } 448 if len(buf) != 0 { 449 err = fd.eofError(n, err) 450 } 451 return n, err 452 } 453 454 var ReadConsole = syscall.ReadConsole // changed for testing 455 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) { 460 if len(b) == 0 { 461 return 0, nil 462 } 463 464 if fd.readuint16 == nil { 465 // Note: syscall.ReadConsole fails for very large buffers. 466 // The limit is somewhere around (but not exactly) 16384. 467 // Stay well below. 468 fd.readuint16 = make([]uint16, 0, 10000) 469 fd.readbyte = make([]byte, 0, 4*cap(fd.readuint16)) 470 } 471 472 for fd.readbyteOffset >= len(fd.readbyte) { 473 n := cap(fd.readuint16) - len(fd.readuint16) 474 if n > len(b) { 475 n = len(b) 476 } 477 var nw uint32 478 err := ReadConsole(fd.Sysfd, &fd.readuint16[:len(fd.readuint16)+1][len(fd.readuint16)], uint32(n), &nw, nil) 479 if err != nil { 480 return 0, err 481 } 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) { 489 if nw > 0 { 490 // Save half surrogate pair for next time. 491 fd.readuint16 = fd.readuint16[:1] 492 fd.readuint16[0] = uint16(r) 493 break 494 } 495 r = utf8.RuneError 496 } else { 497 r = utf16.DecodeRune(r, rune(uint16s[i+1])) 498 if r != utf8.RuneError { 499 i++ 500 } 501 } 502 } 503 n := utf8.EncodeRune(buf[len(buf):cap(buf)], r) 504 buf = buf[:len(buf)+n] 505 } 506 fd.readbyte = buf 507 fd.readbyteOffset = 0 508 if nw == 0 { 509 break 510 } 511 } 512 513 src := fd.readbyte[fd.readbyteOffset:] 514 var i int 515 for i = 0; i < len(src) && i < len(b); i++ { 516 x := src[i] 517 if x == 0x1A { // Ctrl-Z 518 if i == 0 { 519 fd.readbyteOffset++ 520 } 521 break 522 } 523 b[i] = x 524 } 525 fd.readbyteOffset += i 526 return i, nil 527 } 528 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 { 534 return 0, err 535 } 536 defer fd.decref() 537 538 if len(b) > maxRW { 539 b = b[:maxRW] 540 } 541 542 fd.l.Lock() 543 defer fd.l.Unlock() 544 curoffset, e := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent) 545 if e != nil { 546 return 0, e 547 } 548 defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart) 549 o := syscall.Overlapped{ 550 OffsetHigh: uint32(off >> 32), 551 Offset: uint32(off), 552 } 553 var done uint32 554 e = syscall.ReadFile(fd.Sysfd, b, &done, &o) 555 if e != nil { 556 done = 0 557 if e == syscall.ERROR_HANDLE_EOF { 558 e = io.EOF 559 } 560 } 561 if len(b) != 0 { 562 e = fd.eofError(int(done), e) 563 } 564 return int(done), e 565 } 566 567 // ReadFrom wraps the recvfrom network call. 568 func (fd *FD) ReadFrom(buf []byte) (int, syscall.Sockaddr, error) { 569 if len(buf) == 0 { 570 return 0, nil, nil 571 } 572 if len(buf) > maxRW { 573 buf = buf[:maxRW] 574 } 575 if err := fd.readLock(); err != nil { 576 return 0, nil, err 577 } 578 defer fd.readUnlock() 579 o := &fd.rop 580 o.InitBuf(buf) 581 n, err := execIO(o, func(o *operation) error { 582 if o.rsa == nil { 583 o.rsa = new(syscall.RawSockaddrAny) 584 } 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) 587 }) 588 err = fd.eofError(n, err) 589 if err != nil { 590 return n, nil, err 591 } 592 sa, _ := o.rsa.Sockaddr() 593 return n, sa, nil 594 } 595 596 // ReadFromInet4 wraps the recvfrom network call for IPv4. 597 func (fd *FD) ReadFromInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) { 598 if len(buf) == 0 { 599 return 0, nil 600 } 601 if len(buf) > maxRW { 602 buf = buf[:maxRW] 603 } 604 if err := fd.readLock(); err != nil { 605 return 0, err 606 } 607 defer fd.readUnlock() 608 o := &fd.rop 609 o.InitBuf(buf) 610 n, err := execIO(o, func(o *operation) error { 611 if o.rsa == nil { 612 o.rsa = new(syscall.RawSockaddrAny) 613 } 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) 616 }) 617 err = fd.eofError(n, err) 618 if err != nil { 619 return n, err 620 } 621 rawToSockaddrInet4(o.rsa, sa4) 622 return n, err 623 } 624 625 // ReadFromInet6 wraps the recvfrom network call for IPv6. 626 func (fd *FD) ReadFromInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) { 627 if len(buf) == 0 { 628 return 0, nil 629 } 630 if len(buf) > maxRW { 631 buf = buf[:maxRW] 632 } 633 if err := fd.readLock(); err != nil { 634 return 0, err 635 } 636 defer fd.readUnlock() 637 o := &fd.rop 638 o.InitBuf(buf) 639 n, err := execIO(o, func(o *operation) error { 640 if o.rsa == nil { 641 o.rsa = new(syscall.RawSockaddrAny) 642 } 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) 645 }) 646 err = fd.eofError(n, err) 647 if err != nil { 648 return n, err 649 } 650 rawToSockaddrInet6(o.rsa, sa6) 651 return n, err 652 } 653 654 // Write implements io.Writer. 655 func (fd *FD) Write(buf []byte) (int, error) { 656 if err := fd.writeLock(); err != nil { 657 return 0, err 658 } 659 defer fd.writeUnlock() 660 if fd.isFile { 661 fd.l.Lock() 662 defer fd.l.Unlock() 663 } 664 665 ntotal := 0 666 for len(buf) > 0 { 667 b := buf 668 if len(b) > maxRW { 669 b = b[:maxRW] 670 } 671 var n int 672 var err error 673 if fd.isFile { 674 switch fd.kind { 675 case kindConsole: 676 n, err = fd.writeConsole(b) 677 default: 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. 683 err = ErrFileClosing 684 } 685 } 686 if err != nil { 687 n = 0 688 } 689 } else { 690 if race.Enabled { 691 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 692 } 693 o := &fd.wop 694 o.InitBuf(b) 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) 697 }) 698 } 699 ntotal += n 700 if err != nil { 701 return ntotal, err 702 } 703 buf = buf[n:] 704 } 705 return ntotal, nil 706 } 707 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) { 711 n := len(b) 712 runes := make([]rune, 0, 256) 713 if len(fd.lastbits) > 0 { 714 b = append(fd.lastbits, b...) 715 fd.lastbits = nil 716 717 } 718 for len(b) >= utf8.UTFMax || utf8.FullRune(b) { 719 r, l := utf8.DecodeRune(b) 720 runes = append(runes, r) 721 b = b[l:] 722 } 723 if len(b) > 0 { 724 fd.lastbits = make([]byte, len(b)) 725 copy(fd.lastbits, b) 726 } 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 731 for len(runes) > 0 { 732 m := len(runes) 733 if m > maxWrite { 734 m = maxWrite 735 } 736 chunk := runes[:m] 737 runes = runes[m:] 738 uint16s := utf16.Encode(chunk) 739 for len(uint16s) > 0 { 740 var written uint32 741 err := syscall.WriteConsole(fd.Sysfd, &uint16s[0], uint32(len(uint16s)), &written, nil) 742 if err != nil { 743 return 0, err 744 } 745 uint16s = uint16s[written:] 746 } 747 } 748 return n, nil 749 } 750 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 { 756 return 0, err 757 } 758 defer fd.decref() 759 760 fd.l.Lock() 761 defer fd.l.Unlock() 762 curoffset, e := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent) 763 if e != nil { 764 return 0, e 765 } 766 defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart) 767 768 ntotal := 0 769 for len(buf) > 0 { 770 b := buf 771 if len(b) > maxRW { 772 b = b[:maxRW] 773 } 774 var n uint32 775 o := syscall.Overlapped{ 776 OffsetHigh: uint32(off >> 32), 777 Offset: uint32(off), 778 } 779 e = syscall.WriteFile(fd.Sysfd, b, &n, &o) 780 ntotal += int(n) 781 if e != nil { 782 return ntotal, e 783 } 784 buf = buf[n:] 785 off += int64(n) 786 } 787 return ntotal, nil 788 } 789 790 // Writev emulates the Unix writev system call. 791 func (fd *FD) Writev(buf *[][]byte) (int64, error) { 792 if len(*buf) == 0 { 793 return 0, nil 794 } 795 if err := fd.writeLock(); err != nil { 796 return 0, err 797 } 798 defer fd.writeUnlock() 799 if race.Enabled { 800 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 801 } 802 o := &fd.wop 803 o.InitBufs(buf) 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) 806 }) 807 o.ClearBufs() 808 TestHookDidWritev(n) 809 consume(buf, int64(n)) 810 return int64(n), err 811 } 812 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 { 816 return 0, err 817 } 818 defer fd.writeUnlock() 819 820 if len(buf) == 0 { 821 // handle zero-byte payload 822 o := &fd.wop 823 o.InitBuf(buf) 824 o.sa = sa 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) 827 }) 828 return n, err 829 } 830 831 ntotal := 0 832 for len(buf) > 0 { 833 b := buf 834 if len(b) > maxRW { 835 b = b[:maxRW] 836 } 837 o := &fd.wop 838 o.InitBuf(b) 839 o.sa = sa 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) 842 }) 843 ntotal += int(n) 844 if err != nil { 845 return ntotal, err 846 } 847 buf = buf[n:] 848 } 849 return ntotal, nil 850 } 851 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 { 855 return 0, err 856 } 857 defer fd.writeUnlock() 858 859 if len(buf) == 0 { 860 // handle zero-byte payload 861 o := &fd.wop 862 o.InitBuf(buf) 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) 865 }) 866 return n, err 867 } 868 869 ntotal := 0 870 for len(buf) > 0 { 871 b := buf 872 if len(b) > maxRW { 873 b = b[:maxRW] 874 } 875 o := &fd.wop 876 o.InitBuf(b) 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) 879 }) 880 ntotal += int(n) 881 if err != nil { 882 return ntotal, err 883 } 884 buf = buf[n:] 885 } 886 return ntotal, nil 887 } 888 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 { 892 return 0, err 893 } 894 defer fd.writeUnlock() 895 896 if len(buf) == 0 { 897 // handle zero-byte payload 898 o := &fd.wop 899 o.InitBuf(buf) 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) 902 }) 903 return n, err 904 } 905 906 ntotal := 0 907 for len(buf) > 0 { 908 b := buf 909 if len(b) > maxRW { 910 b = b[:maxRW] 911 } 912 o := &fd.wop 913 o.InitBuf(b) 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) 916 }) 917 ntotal += int(n) 918 if err != nil { 919 return ntotal, err 920 } 921 buf = buf[n:] 922 } 923 return ntotal, nil 924 } 925 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 { 930 o := &fd.wop 931 o.sa = ra 932 _, err := execIO(o, func(o *operation) error { 933 return ConnectExFunc(o.fd.Sysfd, o.sa, nil, 0, nil, &o.o) 934 }) 935 return err 936 } 937 938 func (fd *FD) acceptOne(s syscall.Handle, rawsa []syscall.RawSockaddrAny, o *operation) (string, error) { 939 // Submit accept request. 940 o.handle = s 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) 944 }) 945 if err != nil { 946 CloseFunc(s) 947 return "acceptex", err 948 } 949 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))) 952 if err != nil { 953 CloseFunc(s) 954 return "setsockopt", err 955 } 956 957 return "", nil 958 } 959 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 965 } 966 defer fd.readUnlock() 967 968 o := &fd.rop 969 var rawsa [2]syscall.RawSockaddrAny 970 for { 971 s, err := sysSocket() 972 if err != nil { 973 return syscall.InvalidHandle, nil, 0, "", err 974 } 975 976 errcall, err := fd.acceptOne(s, rawsa[:], o) 977 if err == nil { 978 return s, rawsa[:], uint32(o.rsan), "", nil 979 } 980 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) 987 if !ok { 988 return syscall.InvalidHandle, nil, 0, errcall, err 989 } 990 switch errno { 991 case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET: 992 // ignore these and try again 993 default: 994 return syscall.InvalidHandle, nil, 0, errcall, err 995 } 996 } 997 } 998 999 // Seek wraps syscall.Seek. 1000 func (fd *FD) Seek(offset int64, whence int) (int64, error) { 1001 if err := fd.incref(); err != nil { 1002 return 0, err 1003 } 1004 defer fd.decref() 1005 1006 fd.l.Lock() 1007 defer fd.l.Unlock() 1008 1009 return syscall.Seek(fd.Sysfd, offset, whence) 1010 } 1011 1012 // FindNextFile wraps syscall.FindNextFile. 1013 func (fd *FD) FindNextFile(data *syscall.Win32finddata) error { 1014 if err := fd.incref(); err != nil { 1015 return err 1016 } 1017 defer fd.decref() 1018 return syscall.FindNextFile(fd.Sysfd, data) 1019 } 1020 1021 // Fchmod updates syscall.ByHandleFileInformation.Fileattributes when needed. 1022 func (fd *FD) Fchmod(mode uint32) error { 1023 if err := fd.incref(); err != nil { 1024 return err 1025 } 1026 defer fd.decref() 1027 1028 var d syscall.ByHandleFileInformation 1029 if err := syscall.GetFileInformationByHandle(fd.Sysfd, &d); err != nil { 1030 return err 1031 } 1032 attrs := d.FileAttributes 1033 if mode&syscall.S_IWRITE != 0 { 1034 attrs &^= syscall.FILE_ATTRIBUTE_READONLY 1035 } else { 1036 attrs |= syscall.FILE_ATTRIBUTE_READONLY 1037 } 1038 if attrs == d.FileAttributes { 1039 return nil 1040 } 1041 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) 1046 } 1047 1048 // Fchdir wraps syscall.Fchdir. 1049 func (fd *FD) Fchdir() error { 1050 if err := fd.incref(); err != nil { 1051 return err 1052 } 1053 defer fd.decref() 1054 return syscall.Fchdir(fd.Sysfd) 1055 } 1056 1057 // GetFileType wraps syscall.GetFileType. 1058 func (fd *FD) GetFileType() (uint32, error) { 1059 if err := fd.incref(); err != nil { 1060 return 0, err 1061 } 1062 defer fd.decref() 1063 return syscall.GetFileType(fd.Sysfd) 1064 } 1065 1066 // GetFileInformationByHandle wraps GetFileInformationByHandle. 1067 func (fd *FD) GetFileInformationByHandle(data *syscall.ByHandleFileInformation) error { 1068 if err := fd.incref(); err != nil { 1069 return err 1070 } 1071 defer fd.decref() 1072 return syscall.GetFileInformationByHandle(fd.Sysfd, data) 1073 } 1074 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 { 1078 return err 1079 } 1080 defer fd.readUnlock() 1081 for { 1082 if f(uintptr(fd.Sysfd)) { 1083 return nil 1084 } 1085 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 1088 o := &fd.rop 1089 o.InitBuf(nil) 1090 if !fd.IsStream { 1091 o.flags |= windows.MSG_PEEK 1092 } 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) 1095 }) 1096 if err == windows.WSAEMSGSIZE { 1097 // expected with a 0-byte peek, ignore. 1098 } else if err != nil { 1099 return err 1100 } 1101 } 1102 } 1103 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 { 1107 return err 1108 } 1109 defer fd.writeUnlock() 1110 1111 if f(uintptr(fd.Sysfd)) { 1112 return nil 1113 } 1114 1115 // TODO(tmm1): find a way to detect socket writability 1116 return syscall.EWINDOWS 1117 } 1118 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) 1126 raw.Addr = sa.Addr 1127 return int32(unsafe.Sizeof(*raw)) 1128 } 1129 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 1138 raw.Addr = sa.Addr 1139 return int32(unsafe.Sizeof(*raw)) 1140 } 1141 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]) 1146 sa.Addr = pp.Addr 1147 } 1148 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 1154 sa.Addr = pp.Addr 1155 } 1156 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) 1161 return sz, nil 1162 case *syscall.SockaddrInet6: 1163 sz := sockaddrInet6ToRaw(rsa, sa) 1164 return sz, nil 1165 default: 1166 return 0, syscall.EWINDOWS 1167 } 1168 } 1169 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 1174 } 1175 defer fd.readUnlock() 1176 1177 if len(p) > maxRW { 1178 p = p[:maxRW] 1179 } 1180 1181 o := &fd.rop 1182 o.InitMsg(p, oob) 1183 if o.rsa == nil { 1184 o.rsa = new(syscall.RawSockaddrAny) 1185 } 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) 1191 }) 1192 err = fd.eofError(n, err) 1193 var sa syscall.Sockaddr 1194 if err == nil { 1195 sa, err = o.rsa.Sockaddr() 1196 } 1197 return n, int(o.msg.Control.Len), int(o.msg.Flags), sa, err 1198 } 1199 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 { 1203 return 0, 0, 0, err 1204 } 1205 defer fd.readUnlock() 1206 1207 if len(p) > maxRW { 1208 p = p[:maxRW] 1209 } 1210 1211 o := &fd.rop 1212 o.InitMsg(p, oob) 1213 if o.rsa == nil { 1214 o.rsa = new(syscall.RawSockaddrAny) 1215 } 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) 1221 }) 1222 err = fd.eofError(n, err) 1223 if err == nil { 1224 rawToSockaddrInet4(o.rsa, sa4) 1225 } 1226 return n, int(o.msg.Control.Len), int(o.msg.Flags), err 1227 } 1228 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 { 1232 return 0, 0, 0, err 1233 } 1234 defer fd.readUnlock() 1235 1236 if len(p) > maxRW { 1237 p = p[:maxRW] 1238 } 1239 1240 o := &fd.rop 1241 o.InitMsg(p, oob) 1242 if o.rsa == nil { 1243 o.rsa = new(syscall.RawSockaddrAny) 1244 } 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) 1250 }) 1251 err = fd.eofError(n, err) 1252 if err == nil { 1253 rawToSockaddrInet6(o.rsa, sa6) 1254 } 1255 return n, int(o.msg.Control.Len), int(o.msg.Flags), err 1256 } 1257 1258 // WriteMsg wraps the WSASendMsg network call. 1259 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) { 1260 if len(p) > maxRW { 1261 return 0, 0, errors.New("packet is too large (only 1GB is allowed)") 1262 } 1263 1264 if err := fd.writeLock(); err != nil { 1265 return 0, 0, err 1266 } 1267 defer fd.writeUnlock() 1268 1269 o := &fd.wop 1270 o.InitMsg(p, oob) 1271 if sa != nil { 1272 if o.rsa == nil { 1273 o.rsa = new(syscall.RawSockaddrAny) 1274 } 1275 len, err := sockaddrToRaw(o.rsa, sa) 1276 if err != nil { 1277 return 0, 0, err 1278 } 1279 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) 1280 o.msg.Namelen = len 1281 } 1282 n, err := execIO(o, func(o *operation) error { 1283 return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil) 1284 }) 1285 return n, int(o.msg.Control.Len), err 1286 } 1287 1288 // WriteMsgInet4 is WriteMsg specialized for syscall.SockaddrInet4. 1289 func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (int, int, error) { 1290 if len(p) > maxRW { 1291 return 0, 0, errors.New("packet is too large (only 1GB is allowed)") 1292 } 1293 1294 if err := fd.writeLock(); err != nil { 1295 return 0, 0, err 1296 } 1297 defer fd.writeUnlock() 1298 1299 o := &fd.wop 1300 o.InitMsg(p, oob) 1301 if o.rsa == nil { 1302 o.rsa = new(syscall.RawSockaddrAny) 1303 } 1304 len := sockaddrInet4ToRaw(o.rsa, sa) 1305 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) 1306 o.msg.Namelen = len 1307 n, err := execIO(o, func(o *operation) error { 1308 return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil) 1309 }) 1310 return n, int(o.msg.Control.Len), err 1311 } 1312 1313 // WriteMsgInet6 is WriteMsg specialized for syscall.SockaddrInet6. 1314 func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (int, int, error) { 1315 if len(p) > maxRW { 1316 return 0, 0, errors.New("packet is too large (only 1GB is allowed)") 1317 } 1318 1319 if err := fd.writeLock(); err != nil { 1320 return 0, 0, err 1321 } 1322 defer fd.writeUnlock() 1323 1324 o := &fd.wop 1325 o.InitMsg(p, oob) 1326 if o.rsa == nil { 1327 o.rsa = new(syscall.RawSockaddrAny) 1328 } 1329 len := sockaddrInet6ToRaw(o.rsa, sa) 1330 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa)) 1331 o.msg.Namelen = len 1332 n, err := execIO(o, func(o *operation) error { 1333 return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil) 1334 }) 1335 return n, int(o.msg.Control.Len), err 1336 }