github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/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 "internal/race" 10 "internal/syscall/windows" 11 "io" 12 "runtime" 13 "sync" 14 "syscall" 15 "unicode/utf16" 16 "unicode/utf8" 17 "unsafe" 18 ) 19 20 var ( 21 initErr error 22 ioSync uint64 23 ) 24 25 // CancelIo Windows API cancels all outstanding IO for a particular 26 // socket on current thread. To overcome that limitation, we run 27 // special goroutine, locked to OS single thread, that both starts 28 // and cancels IO. It means, there are 2 unavoidable thread switches 29 // for every IO. 30 // Some newer versions of Windows has new CancelIoEx API, that does 31 // not have that limitation and can be used from any thread. This 32 // package uses CancelIoEx API, if present, otherwise it fallback 33 // to CancelIo. 34 35 var canCancelIO bool // determines if CancelIoEx API is present 36 37 // This package uses the SetFileCompletionNotificationModes Windows 38 // API to skip calling GetQueuedCompletionStatus if an IO operation 39 // completes synchronously. There is a known bug where 40 // SetFileCompletionNotificationModes crashes on some systems (see 41 // https://support.microsoft.com/kb/2568167 for details). 42 43 var useSetFileCompletionNotificationModes bool // determines is SetFileCompletionNotificationModes is present and safe to use 44 45 // checkSetFileCompletionNotificationModes verifies that 46 // SetFileCompletionNotificationModes Windows API is present 47 // on the system and is safe to use. 48 // See https://support.microsoft.com/kb/2568167 for details. 49 func checkSetFileCompletionNotificationModes() { 50 err := syscall.LoadSetFileCompletionNotificationModes() 51 if err != nil { 52 return 53 } 54 protos := [2]int32{syscall.IPPROTO_TCP, 0} 55 var buf [32]syscall.WSAProtocolInfo 56 len := uint32(unsafe.Sizeof(buf)) 57 n, err := syscall.WSAEnumProtocols(&protos[0], &buf[0], &len) 58 if err != nil { 59 return 60 } 61 for i := int32(0); i < n; i++ { 62 if buf[i].ServiceFlags1&syscall.XP1_IFS_HANDLES == 0 { 63 return 64 } 65 } 66 useSetFileCompletionNotificationModes = true 67 } 68 69 func init() { 70 var d syscall.WSAData 71 e := syscall.WSAStartup(uint32(0x202), &d) 72 if e != nil { 73 initErr = e 74 } 75 canCancelIO = syscall.LoadCancelIoEx() == nil 76 checkSetFileCompletionNotificationModes() 77 } 78 79 // operation contains superset of data necessary to perform all async IO. 80 type operation struct { 81 // Used by IOCP interface, it must be first field 82 // of the struct, as our code rely on it. 83 o syscall.Overlapped 84 85 // fields used by runtime.netpoll 86 runtimeCtx uintptr 87 mode int32 88 errno int32 89 qty uint32 90 91 // fields used only by net package 92 fd *FD 93 errc chan error 94 buf syscall.WSABuf 95 msg windows.WSAMsg 96 sa syscall.Sockaddr 97 rsa *syscall.RawSockaddrAny 98 rsan int32 99 handle syscall.Handle 100 flags uint32 101 bufs []syscall.WSABuf 102 } 103 104 func (o *operation) InitBuf(buf []byte) { 105 o.buf.Len = uint32(len(buf)) 106 o.buf.Buf = nil 107 if len(buf) != 0 { 108 o.buf.Buf = &buf[0] 109 } 110 } 111 112 func (o *operation) InitBufs(buf *[][]byte) { 113 if o.bufs == nil { 114 o.bufs = make([]syscall.WSABuf, 0, len(*buf)) 115 } else { 116 o.bufs = o.bufs[:0] 117 } 118 for _, b := range *buf { 119 if len(b) == 0 { 120 o.bufs = append(o.bufs, syscall.WSABuf{}) 121 continue 122 } 123 for len(b) > maxRW { 124 o.bufs = append(o.bufs, syscall.WSABuf{Len: maxRW, Buf: &b[0]}) 125 b = b[maxRW:] 126 } 127 if len(b) > 0 { 128 o.bufs = append(o.bufs, syscall.WSABuf{Len: uint32(len(b)), Buf: &b[0]}) 129 } 130 } 131 } 132 133 // ClearBufs clears all pointers to Buffers parameter captured 134 // by InitBufs, so it can be released by garbage collector. 135 func (o *operation) ClearBufs() { 136 for i := range o.bufs { 137 o.bufs[i].Buf = nil 138 } 139 o.bufs = o.bufs[:0] 140 } 141 142 func (o *operation) InitMsg(p []byte, oob []byte) { 143 o.InitBuf(p) 144 o.msg.Buffers = &o.buf 145 o.msg.BufferCount = 1 146 147 o.msg.Name = nil 148 o.msg.Namelen = 0 149 150 o.msg.Flags = 0 151 o.msg.Control.Len = uint32(len(oob)) 152 o.msg.Control.Buf = nil 153 if len(oob) != 0 { 154 o.msg.Control.Buf = &oob[0] 155 } 156 } 157 158 // ioSrv executes net IO requests. 159 type ioSrv struct { 160 req chan ioSrvReq 161 } 162 163 type ioSrvReq struct { 164 o *operation 165 submit func(o *operation) error // if nil, cancel the operation 166 } 167 168 // ProcessRemoteIO will execute submit IO requests on behalf 169 // of other goroutines, all on a single os thread, so it can 170 // cancel them later. Results of all operations will be sent 171 // back to their requesters via channel supplied in request. 172 // It is used only when the CancelIoEx API is unavailable. 173 func (s *ioSrv) ProcessRemoteIO() { 174 runtime.LockOSThread() 175 defer runtime.UnlockOSThread() 176 for r := range s.req { 177 if r.submit != nil { 178 r.o.errc <- r.submit(r.o) 179 } else { 180 r.o.errc <- syscall.CancelIo(r.o.fd.Sysfd) 181 } 182 } 183 } 184 185 // ExecIO executes a single IO operation o. It submits and cancels 186 // IO in the current thread for systems where Windows CancelIoEx API 187 // is available. Alternatively, it passes the request onto 188 // runtime netpoll and waits for completion or cancels request. 189 func (s *ioSrv) ExecIO(o *operation, submit func(o *operation) error) (int, error) { 190 if o.fd.pd.runtimeCtx == 0 { 191 return 0, errors.New("internal error: polling on unsupported descriptor type") 192 } 193 194 if !canCancelIO { 195 onceStartServer.Do(startServer) 196 } 197 198 fd := o.fd 199 // Notify runtime netpoll about starting IO. 200 err := fd.pd.prepare(int(o.mode), fd.isFile) 201 if err != nil { 202 return 0, err 203 } 204 // Start IO. 205 if canCancelIO { 206 err = submit(o) 207 } else { 208 // Send request to a special dedicated thread, 209 // so it can stop the IO with CancelIO later. 210 s.req <- ioSrvReq{o, submit} 211 err = <-o.errc 212 } 213 switch err { 214 case nil: 215 // IO completed immediately 216 if o.fd.skipSyncNotif { 217 // No completion message will follow, so return immediately. 218 return int(o.qty), nil 219 } 220 // Need to get our completion message anyway. 221 case syscall.ERROR_IO_PENDING: 222 // IO started, and we have to wait for its completion. 223 err = nil 224 default: 225 return 0, err 226 } 227 // Wait for our request to complete. 228 err = fd.pd.wait(int(o.mode), fd.isFile) 229 if err == nil { 230 // All is good. Extract our IO results and return. 231 if o.errno != 0 { 232 err = syscall.Errno(o.errno) 233 // More data available. Return back the size of received data. 234 if err == syscall.ERROR_MORE_DATA || err == windows.WSAEMSGSIZE { 235 return int(o.qty), err 236 } 237 return 0, err 238 } 239 return int(o.qty), nil 240 } 241 // IO is interrupted by "close" or "timeout" 242 netpollErr := err 243 switch netpollErr { 244 case ErrNetClosing, ErrFileClosing, ErrTimeout: 245 // will deal with those. 246 default: 247 panic("unexpected runtime.netpoll error: " + netpollErr.Error()) 248 } 249 // Cancel our request. 250 if canCancelIO { 251 err := syscall.CancelIoEx(fd.Sysfd, &o.o) 252 // Assuming ERROR_NOT_FOUND is returned, if IO is completed. 253 if err != nil && err != syscall.ERROR_NOT_FOUND { 254 // TODO(brainman): maybe do something else, but panic. 255 panic(err) 256 } 257 } else { 258 s.req <- ioSrvReq{o, nil} 259 <-o.errc 260 } 261 // Wait for cancelation to complete. 262 fd.pd.waitCanceled(int(o.mode)) 263 if o.errno != 0 { 264 err = syscall.Errno(o.errno) 265 if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled 266 err = netpollErr 267 } 268 return 0, err 269 } 270 // We issued a cancelation request. But, it seems, IO operation succeeded 271 // before the cancelation request run. We need to treat the IO operation as 272 // succeeded (the bytes are actually sent/recv from network). 273 return int(o.qty), nil 274 } 275 276 // Start helper goroutines. 277 var rsrv, wsrv ioSrv 278 var onceStartServer sync.Once 279 280 func startServer() { 281 // This is called, once, when only the CancelIo API is available. 282 // Start two special goroutines, both locked to an OS thread, 283 // that start and cancel IO requests. 284 // One will process read requests, while the other will do writes. 285 rsrv.req = make(chan ioSrvReq) 286 go rsrv.ProcessRemoteIO() 287 wsrv.req = make(chan ioSrvReq) 288 go wsrv.ProcessRemoteIO() 289 } 290 291 // FD is a file descriptor. The net and os packages embed this type in 292 // a larger type representing a network connection or OS file. 293 type FD struct { 294 // Lock sysfd and serialize access to Read and Write methods. 295 fdmu fdMutex 296 297 // System file descriptor. Immutable until Close. 298 Sysfd syscall.Handle 299 300 // Read operation. 301 rop operation 302 // Write operation. 303 wop operation 304 305 // I/O poller. 306 pd pollDesc 307 308 // Used to implement pread/pwrite. 309 l sync.Mutex 310 311 // For console I/O. 312 isConsole bool 313 lastbits []byte // first few bytes of the last incomplete rune in last write 314 readuint16 []uint16 // buffer to hold uint16s obtained with ReadConsole 315 readbyte []byte // buffer to hold decoding of readuint16 from utf16 to utf8 316 readbyteOffset int // readbyte[readOffset:] is yet to be consumed with file.Read 317 318 // Semaphore signaled when file is closed. 319 csema uint32 320 321 skipSyncNotif bool 322 323 // Whether this is a streaming descriptor, as opposed to a 324 // packet-based descriptor like a UDP socket. 325 IsStream bool 326 327 // Whether a zero byte read indicates EOF. This is false for a 328 // message based socket connection. 329 ZeroReadIsEOF bool 330 331 // Whether this is a normal file. 332 isFile bool 333 334 // Whether this is a directory. 335 isDir bool 336 } 337 338 // logInitFD is set by tests to enable file descriptor initialization logging. 339 var logInitFD func(net string, fd *FD, err error) 340 341 // Init initializes the FD. The Sysfd field should already be set. 342 // This can be called multiple times on a single FD. 343 // The net argument is a network name from the net package (e.g., "tcp"), 344 // or "file" or "console" or "dir". 345 // Set pollable to true if fd should be managed by runtime netpoll. 346 func (fd *FD) Init(net string, pollable bool) (string, error) { 347 if initErr != nil { 348 return "", initErr 349 } 350 351 switch net { 352 case "file": 353 fd.isFile = true 354 case "console": 355 fd.isConsole = true 356 case "dir": 357 fd.isDir = true 358 case "tcp", "tcp4", "tcp6": 359 case "udp", "udp4", "udp6": 360 case "ip", "ip4", "ip6": 361 case "unix", "unixgram", "unixpacket": 362 default: 363 return "", errors.New("internal error: unknown network type " + net) 364 } 365 366 var err error 367 if pollable { 368 // Only call init for a network socket. 369 // This means that we don't add files to the runtime poller. 370 // Adding files to the runtime poller can confuse matters 371 // if the user is doing their own overlapped I/O. 372 // See issue #21172. 373 // 374 // In general the code below avoids calling the ExecIO 375 // method for non-network sockets. If some method does 376 // somehow call ExecIO, then ExecIO, and therefore the 377 // calling method, will return an error, because 378 // fd.pd.runtimeCtx will be 0. 379 err = fd.pd.init(fd) 380 } 381 if logInitFD != nil { 382 logInitFD(net, fd, err) 383 } 384 if err != nil { 385 return "", err 386 } 387 if pollable && useSetFileCompletionNotificationModes { 388 // We do not use events, so we can skip them always. 389 flags := uint8(syscall.FILE_SKIP_SET_EVENT_ON_HANDLE) 390 // It's not safe to skip completion notifications for UDP: 391 // https://blogs.technet.com/b/winserverperformance/archive/2008/06/26/designing-applications-for-high-performance-part-iii.aspx 392 if net == "tcp" { 393 flags |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 394 } 395 err := syscall.SetFileCompletionNotificationModes(fd.Sysfd, flags) 396 if err == nil && flags&syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS != 0 { 397 fd.skipSyncNotif = true 398 } 399 } 400 // Disable SIO_UDP_CONNRESET behavior. 401 // http://support.microsoft.com/kb/263823 402 switch net { 403 case "udp", "udp4", "udp6": 404 ret := uint32(0) 405 flag := uint32(0) 406 size := uint32(unsafe.Sizeof(flag)) 407 err := syscall.WSAIoctl(fd.Sysfd, syscall.SIO_UDP_CONNRESET, (*byte)(unsafe.Pointer(&flag)), size, nil, 0, &ret, nil, 0) 408 if err != nil { 409 return "wsaioctl", err 410 } 411 } 412 fd.rop.mode = 'r' 413 fd.wop.mode = 'w' 414 fd.rop.fd = fd 415 fd.wop.fd = fd 416 fd.rop.runtimeCtx = fd.pd.runtimeCtx 417 fd.wop.runtimeCtx = fd.pd.runtimeCtx 418 if !canCancelIO { 419 fd.rop.errc = make(chan error) 420 fd.wop.errc = make(chan error) 421 } 422 return "", nil 423 } 424 425 func (fd *FD) destroy() error { 426 if fd.Sysfd == syscall.InvalidHandle { 427 return syscall.EINVAL 428 } 429 // Poller may want to unregister fd in readiness notification mechanism, 430 // so this must be executed before fd.CloseFunc. 431 fd.pd.close() 432 var err error 433 if fd.isFile || fd.isConsole { 434 err = syscall.CloseHandle(fd.Sysfd) 435 } else if fd.isDir { 436 err = syscall.FindClose(fd.Sysfd) 437 } else { 438 // The net package uses the CloseFunc variable for testing. 439 err = CloseFunc(fd.Sysfd) 440 } 441 fd.Sysfd = syscall.InvalidHandle 442 runtime_Semrelease(&fd.csema) 443 return err 444 } 445 446 // Close closes the FD. The underlying file descriptor is closed by 447 // the destroy method when there are no remaining references. 448 func (fd *FD) Close() error { 449 if !fd.fdmu.increfAndClose() { 450 return errClosing(fd.isFile) 451 } 452 // unblock pending reader and writer 453 fd.pd.evict() 454 err := fd.decref() 455 // Wait until the descriptor is closed. If this was the only 456 // reference, it is already closed. 457 runtime_Semacquire(&fd.csema) 458 return err 459 } 460 461 // Shutdown wraps the shutdown network call. 462 func (fd *FD) Shutdown(how int) error { 463 if err := fd.incref(); err != nil { 464 return err 465 } 466 defer fd.decref() 467 return syscall.Shutdown(fd.Sysfd, how) 468 } 469 470 // Windows ReadFile and WSARecv use DWORD (uint32) parameter to pass buffer length. 471 // This prevents us reading blocks larger than 4GB. 472 // See golang.org/issue/26923. 473 const maxRW = 1 << 30 // 1GB is large enough and keeps subsequent reads aligned 474 475 // Read implements io.Reader. 476 func (fd *FD) Read(buf []byte) (int, error) { 477 if err := fd.readLock(); err != nil { 478 return 0, err 479 } 480 defer fd.readUnlock() 481 482 if len(buf) > maxRW { 483 buf = buf[:maxRW] 484 } 485 486 var n int 487 var err error 488 if fd.isFile || fd.isDir || fd.isConsole { 489 fd.l.Lock() 490 defer fd.l.Unlock() 491 if fd.isConsole { 492 n, err = fd.readConsole(buf) 493 } else { 494 n, err = syscall.Read(fd.Sysfd, buf) 495 } 496 if err != nil { 497 n = 0 498 } 499 } else { 500 o := &fd.rop 501 o.InitBuf(buf) 502 n, err = rsrv.ExecIO(o, func(o *operation) error { 503 return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil) 504 }) 505 if race.Enabled { 506 race.Acquire(unsafe.Pointer(&ioSync)) 507 } 508 } 509 if len(buf) != 0 { 510 err = fd.eofError(n, err) 511 } 512 return n, err 513 } 514 515 var ReadConsole = syscall.ReadConsole // changed for testing 516 517 // readConsole reads utf16 characters from console File, 518 // encodes them into utf8 and stores them in buffer b. 519 // It returns the number of utf8 bytes read and an error, if any. 520 func (fd *FD) readConsole(b []byte) (int, error) { 521 if len(b) == 0 { 522 return 0, nil 523 } 524 525 if fd.readuint16 == nil { 526 // Note: syscall.ReadConsole fails for very large buffers. 527 // The limit is somewhere around (but not exactly) 16384. 528 // Stay well below. 529 fd.readuint16 = make([]uint16, 0, 10000) 530 fd.readbyte = make([]byte, 0, 4*cap(fd.readuint16)) 531 } 532 533 for fd.readbyteOffset >= len(fd.readbyte) { 534 n := cap(fd.readuint16) - len(fd.readuint16) 535 if n > len(b) { 536 n = len(b) 537 } 538 var nw uint32 539 err := ReadConsole(fd.Sysfd, &fd.readuint16[:len(fd.readuint16)+1][len(fd.readuint16)], uint32(n), &nw, nil) 540 if err != nil { 541 return 0, err 542 } 543 uint16s := fd.readuint16[:len(fd.readuint16)+int(nw)] 544 fd.readuint16 = fd.readuint16[:0] 545 buf := fd.readbyte[:0] 546 for i := 0; i < len(uint16s); i++ { 547 r := rune(uint16s[i]) 548 if utf16.IsSurrogate(r) { 549 if i+1 == len(uint16s) { 550 if nw > 0 { 551 // Save half surrogate pair for next time. 552 fd.readuint16 = fd.readuint16[:1] 553 fd.readuint16[0] = uint16(r) 554 break 555 } 556 r = utf8.RuneError 557 } else { 558 r = utf16.DecodeRune(r, rune(uint16s[i+1])) 559 if r != utf8.RuneError { 560 i++ 561 } 562 } 563 } 564 n := utf8.EncodeRune(buf[len(buf):cap(buf)], r) 565 buf = buf[:len(buf)+n] 566 } 567 fd.readbyte = buf 568 fd.readbyteOffset = 0 569 if nw == 0 { 570 break 571 } 572 } 573 574 src := fd.readbyte[fd.readbyteOffset:] 575 var i int 576 for i = 0; i < len(src) && i < len(b); i++ { 577 x := src[i] 578 if x == 0x1A { // Ctrl-Z 579 if i == 0 { 580 fd.readbyteOffset++ 581 } 582 break 583 } 584 b[i] = x 585 } 586 fd.readbyteOffset += i 587 return i, nil 588 } 589 590 // Pread emulates the Unix pread system call. 591 func (fd *FD) Pread(b []byte, off int64) (int, error) { 592 // Call incref, not readLock, because since pread specifies the 593 // offset it is independent from other reads. 594 if err := fd.incref(); err != nil { 595 return 0, err 596 } 597 defer fd.decref() 598 599 if len(b) > maxRW { 600 b = b[:maxRW] 601 } 602 603 fd.l.Lock() 604 defer fd.l.Unlock() 605 curoffset, e := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent) 606 if e != nil { 607 return 0, e 608 } 609 defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart) 610 o := syscall.Overlapped{ 611 OffsetHigh: uint32(off >> 32), 612 Offset: uint32(off), 613 } 614 var done uint32 615 e = syscall.ReadFile(fd.Sysfd, b, &done, &o) 616 if e != nil { 617 done = 0 618 if e == syscall.ERROR_HANDLE_EOF { 619 e = io.EOF 620 } 621 } 622 if len(b) != 0 { 623 e = fd.eofError(int(done), e) 624 } 625 return int(done), e 626 } 627 628 // ReadFrom wraps the recvfrom network call. 629 func (fd *FD) ReadFrom(buf []byte) (int, syscall.Sockaddr, error) { 630 if len(buf) == 0 { 631 return 0, nil, nil 632 } 633 if len(buf) > maxRW { 634 buf = buf[:maxRW] 635 } 636 if err := fd.readLock(); err != nil { 637 return 0, nil, err 638 } 639 defer fd.readUnlock() 640 o := &fd.rop 641 o.InitBuf(buf) 642 n, err := rsrv.ExecIO(o, func(o *operation) error { 643 if o.rsa == nil { 644 o.rsa = new(syscall.RawSockaddrAny) 645 } 646 o.rsan = int32(unsafe.Sizeof(*o.rsa)) 647 return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil) 648 }) 649 err = fd.eofError(n, err) 650 if err != nil { 651 return n, nil, err 652 } 653 sa, _ := o.rsa.Sockaddr() 654 return n, sa, nil 655 } 656 657 // Write implements io.Writer. 658 func (fd *FD) Write(buf []byte) (int, error) { 659 if err := fd.writeLock(); err != nil { 660 return 0, err 661 } 662 defer fd.writeUnlock() 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 || fd.isDir || fd.isConsole { 673 fd.l.Lock() 674 defer fd.l.Unlock() 675 if fd.isConsole { 676 n, err = fd.writeConsole(b) 677 } else { 678 n, err = syscall.Write(fd.Sysfd, b) 679 } 680 if err != nil { 681 n = 0 682 } 683 } else { 684 if race.Enabled { 685 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 686 } 687 o := &fd.wop 688 o.InitBuf(b) 689 n, err = wsrv.ExecIO(o, func(o *operation) error { 690 return syscall.WSASend(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil) 691 }) 692 } 693 ntotal += n 694 if err != nil { 695 return ntotal, err 696 } 697 buf = buf[n:] 698 } 699 return ntotal, nil 700 } 701 702 // writeConsole writes len(b) bytes to the console File. 703 // It returns the number of bytes written and an error, if any. 704 func (fd *FD) writeConsole(b []byte) (int, error) { 705 n := len(b) 706 runes := make([]rune, 0, 256) 707 if len(fd.lastbits) > 0 { 708 b = append(fd.lastbits, b...) 709 fd.lastbits = nil 710 711 } 712 for len(b) >= utf8.UTFMax || utf8.FullRune(b) { 713 r, l := utf8.DecodeRune(b) 714 runes = append(runes, r) 715 b = b[l:] 716 } 717 if len(b) > 0 { 718 fd.lastbits = make([]byte, len(b)) 719 copy(fd.lastbits, b) 720 } 721 // syscall.WriteConsole seems to fail, if given large buffer. 722 // So limit the buffer to 16000 characters. This number was 723 // discovered by experimenting with syscall.WriteConsole. 724 const maxWrite = 16000 725 for len(runes) > 0 { 726 m := len(runes) 727 if m > maxWrite { 728 m = maxWrite 729 } 730 chunk := runes[:m] 731 runes = runes[m:] 732 uint16s := utf16.Encode(chunk) 733 for len(uint16s) > 0 { 734 var written uint32 735 err := syscall.WriteConsole(fd.Sysfd, &uint16s[0], uint32(len(uint16s)), &written, nil) 736 if err != nil { 737 return 0, err 738 } 739 uint16s = uint16s[written:] 740 } 741 } 742 return n, nil 743 } 744 745 // Pwrite emulates the Unix pwrite system call. 746 func (fd *FD) Pwrite(buf []byte, off int64) (int, error) { 747 // Call incref, not writeLock, because since pwrite specifies the 748 // offset it is independent from other writes. 749 if err := fd.incref(); err != nil { 750 return 0, err 751 } 752 defer fd.decref() 753 754 fd.l.Lock() 755 defer fd.l.Unlock() 756 curoffset, e := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent) 757 if e != nil { 758 return 0, e 759 } 760 defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart) 761 762 ntotal := 0 763 for len(buf) > 0 { 764 b := buf 765 if len(b) > maxRW { 766 b = b[:maxRW] 767 } 768 var n uint32 769 o := syscall.Overlapped{ 770 OffsetHigh: uint32(off >> 32), 771 Offset: uint32(off), 772 } 773 e = syscall.WriteFile(fd.Sysfd, b, &n, &o) 774 ntotal += int(n) 775 if e != nil { 776 return ntotal, e 777 } 778 buf = buf[n:] 779 off += int64(n) 780 } 781 return ntotal, nil 782 } 783 784 // Writev emulates the Unix writev system call. 785 func (fd *FD) Writev(buf *[][]byte) (int64, error) { 786 if len(*buf) == 0 { 787 return 0, nil 788 } 789 if err := fd.writeLock(); err != nil { 790 return 0, err 791 } 792 defer fd.writeUnlock() 793 if race.Enabled { 794 race.ReleaseMerge(unsafe.Pointer(&ioSync)) 795 } 796 o := &fd.wop 797 o.InitBufs(buf) 798 n, err := wsrv.ExecIO(o, func(o *operation) error { 799 return syscall.WSASend(o.fd.Sysfd, &o.bufs[0], uint32(len(o.bufs)), &o.qty, 0, &o.o, nil) 800 }) 801 o.ClearBufs() 802 TestHookDidWritev(n) 803 consume(buf, int64(n)) 804 return int64(n), err 805 } 806 807 // WriteTo wraps the sendto network call. 808 func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) { 809 if err := fd.writeLock(); err != nil { 810 return 0, err 811 } 812 defer fd.writeUnlock() 813 814 if len(buf) == 0 { 815 // handle zero-byte payload 816 o := &fd.wop 817 o.InitBuf(buf) 818 o.sa = sa 819 n, err := wsrv.ExecIO(o, func(o *operation) error { 820 return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil) 821 }) 822 return n, err 823 } 824 825 ntotal := 0 826 for len(buf) > 0 { 827 b := buf 828 if len(b) > maxRW { 829 b = b[:maxRW] 830 } 831 o := &fd.wop 832 o.InitBuf(b) 833 o.sa = sa 834 n, err := wsrv.ExecIO(o, func(o *operation) error { 835 return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil) 836 }) 837 ntotal += int(n) 838 if err != nil { 839 return ntotal, err 840 } 841 buf = buf[n:] 842 } 843 return ntotal, nil 844 } 845 846 // Call ConnectEx. This doesn't need any locking, since it is only 847 // called when the descriptor is first created. This is here rather 848 // than in the net package so that it can use fd.wop. 849 func (fd *FD) ConnectEx(ra syscall.Sockaddr) error { 850 o := &fd.wop 851 o.sa = ra 852 _, err := wsrv.ExecIO(o, func(o *operation) error { 853 return ConnectExFunc(o.fd.Sysfd, o.sa, nil, 0, nil, &o.o) 854 }) 855 return err 856 } 857 858 func (fd *FD) acceptOne(s syscall.Handle, rawsa []syscall.RawSockaddrAny, o *operation) (string, error) { 859 // Submit accept request. 860 o.handle = s 861 o.rsan = int32(unsafe.Sizeof(rawsa[0])) 862 _, err := rsrv.ExecIO(o, func(o *operation) error { 863 return AcceptFunc(o.fd.Sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o) 864 }) 865 if err != nil { 866 CloseFunc(s) 867 return "acceptex", err 868 } 869 870 // Inherit properties of the listening socket. 871 err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.Sysfd)), int32(unsafe.Sizeof(fd.Sysfd))) 872 if err != nil { 873 CloseFunc(s) 874 return "setsockopt", err 875 } 876 877 return "", nil 878 } 879 880 // Accept handles accepting a socket. The sysSocket parameter is used 881 // to allocate the net socket. 882 func (fd *FD) Accept(sysSocket func() (syscall.Handle, error)) (syscall.Handle, []syscall.RawSockaddrAny, uint32, string, error) { 883 if err := fd.readLock(); err != nil { 884 return syscall.InvalidHandle, nil, 0, "", err 885 } 886 defer fd.readUnlock() 887 888 o := &fd.rop 889 var rawsa [2]syscall.RawSockaddrAny 890 for { 891 s, err := sysSocket() 892 if err != nil { 893 return syscall.InvalidHandle, nil, 0, "", err 894 } 895 896 errcall, err := fd.acceptOne(s, rawsa[:], o) 897 if err == nil { 898 return s, rawsa[:], uint32(o.rsan), "", nil 899 } 900 901 // Sometimes we see WSAECONNRESET and ERROR_NETNAME_DELETED is 902 // returned here. These happen if connection reset is received 903 // before AcceptEx could complete. These errors relate to new 904 // connection, not to AcceptEx, so ignore broken connection and 905 // try AcceptEx again for more connections. 906 errno, ok := err.(syscall.Errno) 907 if !ok { 908 return syscall.InvalidHandle, nil, 0, errcall, err 909 } 910 switch errno { 911 case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET: 912 // ignore these and try again 913 default: 914 return syscall.InvalidHandle, nil, 0, errcall, err 915 } 916 } 917 } 918 919 // Seek wraps syscall.Seek. 920 func (fd *FD) Seek(offset int64, whence int) (int64, error) { 921 if err := fd.incref(); err != nil { 922 return 0, err 923 } 924 defer fd.decref() 925 926 fd.l.Lock() 927 defer fd.l.Unlock() 928 929 return syscall.Seek(fd.Sysfd, offset, whence) 930 } 931 932 // FindNextFile wraps syscall.FindNextFile. 933 func (fd *FD) FindNextFile(data *syscall.Win32finddata) error { 934 if err := fd.incref(); err != nil { 935 return err 936 } 937 defer fd.decref() 938 return syscall.FindNextFile(fd.Sysfd, data) 939 } 940 941 // Fchdir wraps syscall.Fchdir. 942 func (fd *FD) Fchdir() error { 943 if err := fd.incref(); err != nil { 944 return err 945 } 946 defer fd.decref() 947 return syscall.Fchdir(fd.Sysfd) 948 } 949 950 // GetFileType wraps syscall.GetFileType. 951 func (fd *FD) GetFileType() (uint32, error) { 952 if err := fd.incref(); err != nil { 953 return 0, err 954 } 955 defer fd.decref() 956 return syscall.GetFileType(fd.Sysfd) 957 } 958 959 // GetFileInformationByHandle wraps GetFileInformationByHandle. 960 func (fd *FD) GetFileInformationByHandle(data *syscall.ByHandleFileInformation) error { 961 if err := fd.incref(); err != nil { 962 return err 963 } 964 defer fd.decref() 965 return syscall.GetFileInformationByHandle(fd.Sysfd, data) 966 } 967 968 // RawControl invokes the user-defined function f for a non-IO 969 // operation. 970 func (fd *FD) RawControl(f func(uintptr)) error { 971 if err := fd.incref(); err != nil { 972 return err 973 } 974 defer fd.decref() 975 f(uintptr(fd.Sysfd)) 976 return nil 977 } 978 979 // RawRead invokes the user-defined function f for a read operation. 980 func (fd *FD) RawRead(f func(uintptr) bool) error { 981 if err := fd.readLock(); err != nil { 982 return err 983 } 984 defer fd.readUnlock() 985 for { 986 if f(uintptr(fd.Sysfd)) { 987 return nil 988 } 989 990 // Use a zero-byte read as a way to get notified when this 991 // socket is readable. h/t https://stackoverflow.com/a/42019668/332798 992 o := &fd.rop 993 o.InitBuf(nil) 994 if !fd.IsStream { 995 o.flags |= windows.MSG_PEEK 996 } 997 _, err := rsrv.ExecIO(o, func(o *operation) error { 998 return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil) 999 }) 1000 if err == windows.WSAEMSGSIZE { 1001 // expected with a 0-byte peek, ignore. 1002 } else if err != nil { 1003 return err 1004 } 1005 } 1006 } 1007 1008 // RawWrite invokes the user-defined function f for a write operation. 1009 func (fd *FD) RawWrite(f func(uintptr) bool) error { 1010 if err := fd.writeLock(); err != nil { 1011 return err 1012 } 1013 defer fd.writeUnlock() 1014 1015 if f(uintptr(fd.Sysfd)) { 1016 return nil 1017 } 1018 1019 // TODO(tmm1): find a way to detect socket writability 1020 return syscall.EWINDOWS 1021 } 1022 1023 func sockaddrToRaw(sa syscall.Sockaddr) (unsafe.Pointer, int32, error) { 1024 switch sa := sa.(type) { 1025 case *syscall.SockaddrInet4: 1026 var raw syscall.RawSockaddrInet4 1027 raw.Family = syscall.AF_INET 1028 p := (*[2]byte)(unsafe.Pointer(&raw.Port)) 1029 p[0] = byte(sa.Port >> 8) 1030 p[1] = byte(sa.Port) 1031 for i := 0; i < len(sa.Addr); i++ { 1032 raw.Addr[i] = sa.Addr[i] 1033 } 1034 return unsafe.Pointer(&raw), int32(unsafe.Sizeof(raw)), nil 1035 case *syscall.SockaddrInet6: 1036 var raw syscall.RawSockaddrInet6 1037 raw.Family = syscall.AF_INET6 1038 p := (*[2]byte)(unsafe.Pointer(&raw.Port)) 1039 p[0] = byte(sa.Port >> 8) 1040 p[1] = byte(sa.Port) 1041 raw.Scope_id = sa.ZoneId 1042 for i := 0; i < len(sa.Addr); i++ { 1043 raw.Addr[i] = sa.Addr[i] 1044 } 1045 return unsafe.Pointer(&raw), int32(unsafe.Sizeof(raw)), nil 1046 default: 1047 return nil, 0, syscall.EWINDOWS 1048 } 1049 } 1050 1051 // ReadMsg wraps the WSARecvMsg network call. 1052 func (fd *FD) ReadMsg(p []byte, oob []byte) (int, int, int, syscall.Sockaddr, error) { 1053 if err := fd.readLock(); err != nil { 1054 return 0, 0, 0, nil, err 1055 } 1056 defer fd.readUnlock() 1057 1058 if len(p) > maxRW { 1059 p = p[:maxRW] 1060 } 1061 1062 o := &fd.rop 1063 o.InitMsg(p, oob) 1064 o.rsa = new(syscall.RawSockaddrAny) 1065 o.msg.Name = o.rsa 1066 o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa)) 1067 n, err := rsrv.ExecIO(o, func(o *operation) error { 1068 return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil) 1069 }) 1070 err = fd.eofError(n, err) 1071 var sa syscall.Sockaddr 1072 if err == nil { 1073 sa, err = o.rsa.Sockaddr() 1074 } 1075 return n, int(o.msg.Control.Len), int(o.msg.Flags), sa, err 1076 } 1077 1078 // WriteMsg wraps the WSASendMsg network call. 1079 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) { 1080 if len(p) > maxRW { 1081 return 0, 0, errors.New("packet is too large (only 1GB is allowed)") 1082 } 1083 1084 if err := fd.writeLock(); err != nil { 1085 return 0, 0, err 1086 } 1087 defer fd.writeUnlock() 1088 1089 o := &fd.wop 1090 o.InitMsg(p, oob) 1091 if sa != nil { 1092 rsa, len, err := sockaddrToRaw(sa) 1093 if err != nil { 1094 return 0, 0, err 1095 } 1096 o.msg.Name = (*syscall.RawSockaddrAny)(rsa) 1097 o.msg.Namelen = len 1098 } 1099 n, err := wsrv.ExecIO(o, func(o *operation) error { 1100 return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil) 1101 }) 1102 return n, int(o.msg.Control.Len), err 1103 }