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