1
2
3
4
5 package poll
6
7 import (
8 "errors"
9 "internal/race"
10 "internal/syscall/windows"
11 "io"
12 "runtime"
13 "sync"
14 "sync/atomic"
15 "syscall"
16 "unicode/utf16"
17 "unicode/utf8"
18 "unsafe"
19 )
20
21 var (
22 initErr error
23 ioSync uint64
24 )
25
26
27
28 var ifsHandlesOnly = sync.OnceValue(func() bool {
29 protos := [2]int32{syscall.IPPROTO_TCP, 0}
30 var buf [32]syscall.WSAProtocolInfo
31 len := uint32(unsafe.Sizeof(buf))
32 n, err := syscall.WSAEnumProtocols(&protos[0], &buf[0], &len)
33 if err != nil {
34 return false
35 }
36 for i := range n {
37 if buf[i].ServiceFlags1&syscall.XP1_IFS_HANDLES == 0 {
38 return false
39 }
40 }
41 return true
42 })
43
44
45
46 func canSkipCompletionPortOnSuccess(h syscall.Handle, isSocket bool) bool {
47 if !isSocket {
48
49 return true
50 }
51 if ifsHandlesOnly() {
52
53 return true
54 }
55 var info syscall.WSAProtocolInfo
56 size := int32(unsafe.Sizeof(info))
57 if syscall.Getsockopt(h, syscall.SOL_SOCKET, windows.SO_PROTOCOL_INFOW, (*byte)(unsafe.Pointer(&info)), &size) != nil {
58 return false
59 }
60 return info.ServiceFlags1&syscall.XP1_IFS_HANDLES != 0
61 }
62
63
64
65
66 var InitWSA = sync.OnceFunc(func() {
67 var d syscall.WSAData
68 e := syscall.WSAStartup(uint32(0x202), &d)
69 if e != nil {
70 initErr = e
71 }
72 })
73
74
75 type operation struct {
76
77
78 o syscall.Overlapped
79
80
81 runtimeCtx uintptr
82 mode int32
83 }
84
85 func (o *operation) setOffset(off int64) {
86 o.o.OffsetHigh = uint32(off >> 32)
87 o.o.Offset = uint32(off)
88 }
89
90 func (fd *FD) overlapped(o *operation) *syscall.Overlapped {
91 if fd.isBlocking {
92
93
94
95
96 return nil
97 }
98 return &o.o
99 }
100
101 func newWsaBuf(b []byte) *syscall.WSABuf {
102 return &syscall.WSABuf{Buf: unsafe.SliceData(b), Len: uint32(len(b))}
103 }
104
105 var wsaBufsPool = sync.Pool{
106 New: func() any {
107 buf := make([]syscall.WSABuf, 0, 16)
108 return &buf
109 },
110 }
111
112 func newWSABufs(buf *[][]byte) *[]syscall.WSABuf {
113 bufsPtr := wsaBufsPool.Get().(*[]syscall.WSABuf)
114 *bufsPtr = (*bufsPtr)[:0]
115 for _, b := range *buf {
116 if len(b) == 0 {
117 *bufsPtr = append(*bufsPtr, syscall.WSABuf{})
118 continue
119 }
120 for len(b) > maxRW {
121 *bufsPtr = append(*bufsPtr, syscall.WSABuf{Len: maxRW, Buf: &b[0]})
122 b = b[maxRW:]
123 }
124 if len(b) > 0 {
125 *bufsPtr = append(*bufsPtr, syscall.WSABuf{Len: uint32(len(b)), Buf: &b[0]})
126 }
127 }
128 return bufsPtr
129 }
130
131 func freeWSABufs(bufsPtr *[]syscall.WSABuf) {
132
133 bufs := *bufsPtr
134 for i := range bufs {
135 bufs[i].Buf = nil
136 }
137
138
139
140
141
142
143 if cap(*bufsPtr) > 128 {
144 *bufsPtr = nil
145 }
146 wsaBufsPool.Put(bufsPtr)
147 }
148
149
150 var wsaMsgPool = sync.Pool{
151 New: func() any {
152 return &windows.WSAMsg{
153 Buffers: &syscall.WSABuf{},
154 BufferCount: 1,
155 }
156 },
157 }
158
159
160
161 func newWSAMsg(p []byte, oob []byte, flags int, unconnected bool) *windows.WSAMsg {
162
163
164
165
166
167
168 msg := wsaMsgPool.Get().(*windows.WSAMsg)
169 msg.Buffers.Len = uint32(len(p))
170 msg.Buffers.Buf = unsafe.SliceData(p)
171 msg.Control = syscall.WSABuf{
172 Len: uint32(len(oob)),
173 Buf: unsafe.SliceData(oob),
174 }
175 msg.Flags = uint32(flags)
176 if unconnected {
177 msg.Name = wsaRsaPool.Get().(*syscall.RawSockaddrAny)
178 msg.Namelen = int32(unsafe.Sizeof(syscall.RawSockaddrAny{}))
179 }
180 return msg
181 }
182
183 func freeWSAMsg(msg *windows.WSAMsg) {
184
185 msg.Buffers.Len = 0
186 msg.Buffers.Buf = nil
187 msg.Control.Len = 0
188 msg.Control.Buf = nil
189 if msg.Name != nil {
190 *msg.Name = syscall.RawSockaddrAny{}
191 wsaRsaPool.Put(msg.Name)
192 msg.Name = nil
193 msg.Namelen = 0
194 }
195 wsaMsgPool.Put(msg)
196 }
197
198 var wsaRsaPool = sync.Pool{
199 New: func() any {
200 return new(syscall.RawSockaddrAny)
201 },
202 }
203
204 var operationPool = sync.Pool{
205 New: func() any {
206 return new(operation)
207 },
208 }
209
210
211
212 func (fd *FD) waitIO(o *operation) error {
213 if o.o.HEvent != 0 {
214
215
216
217 _, err := syscall.WaitForSingleObject(o.o.HEvent, syscall.INFINITE)
218 return err
219 }
220
221 err := fd.pd.wait(int(o.mode), fd.isFile)
222 switch err {
223 case nil:
224
225 case ErrNetClosing, ErrFileClosing, ErrDeadlineExceeded:
226
227
228
229 if err := syscall.CancelIoEx(fd.Sysfd, &o.o); err != nil && err != syscall.ERROR_NOT_FOUND {
230
231 panic(err)
232 }
233 fd.pd.waitCanceled(int(o.mode))
234 default:
235
236 panic("unexpected runtime.netpoll error: " + err.Error())
237 }
238 return err
239 }
240
241
242
243
244 func (fd *FD) execIO(mode int, submit func(o *operation) (uint32, error), buf []byte) (int, error) {
245
246 err := fd.pd.prepare(mode, fd.isFile)
247 if err != nil {
248 return 0, err
249 }
250 o := operationPool.Get().(*operation)
251 defer operationPool.Put(o)
252 *o = operation{
253 runtimeCtx: fd.pd.runtimeCtx,
254 mode: int32(mode),
255 }
256 o.setOffset(fd.offset)
257 if !fd.isBlocking {
258 if len(buf) > 0 {
259 ptr := unsafe.SliceData(buf)
260 if mode == 'r' {
261 fd.readPinner.Pin(ptr)
262 } else {
263 fd.writePinner.Pin(ptr)
264 }
265 defer func() {
266 if mode == 'r' {
267 fd.readPinner.Unpin()
268 } else {
269 fd.writePinner.Unpin()
270 }
271 }()
272 }
273 if !fd.pollable() {
274
275
276
277 h, err := windows.CreateEvent(nil, 0, 0, nil)
278 if err != nil {
279
280 panic(err)
281 }
282
283 o.o.HEvent = h | 1
284 defer syscall.CloseHandle(h)
285 }
286 }
287
288 qty, err := submit(o)
289 var waitErr error
290
291
292 if !fd.isBlocking && (err == syscall.ERROR_IO_PENDING || (err == nil && fd.waitOnSuccess)) {
293
294
295 waitErr = fd.waitIO(o)
296 if fd.isFile {
297 err = windows.GetOverlappedResult(fd.Sysfd, &o.o, &qty, false)
298 } else {
299 var flags uint32
300 err = windows.WSAGetOverlappedResult(fd.Sysfd, &o.o, &qty, false, &flags)
301 }
302 }
303 switch err {
304 case syscall.ERROR_OPERATION_ABORTED:
305
306
307
308 if waitErr != nil {
309
310 err = waitErr
311 } else if fd.kind == kindPipe && fd.closing() {
312
313
314
315 err = errClosing(fd.isFile)
316 }
317 case windows.ERROR_IO_INCOMPLETE:
318
319 if waitErr != nil {
320
321 err = waitErr
322 }
323 }
324 return int(qty), err
325 }
326
327
328
329 type FD struct {
330
331 fdmu fdMutex
332
333
334 Sysfd syscall.Handle
335
336
337 pd pollDesc
338
339
340
341
342 offset int64
343
344
345 lastbits []byte
346 readuint16 []uint16
347 readbyte []byte
348 readbyteOffset int
349
350
351 csema uint32
352
353
354
355 waitOnSuccess bool
356
357
358
359 IsStream bool
360
361
362
363 ZeroReadIsEOF bool
364
365
366 isFile bool
367
368
369 kind fileKind
370
371
372 isBlocking bool
373
374 disassociated atomic.Bool
375
376
377
378 readPinner runtime.Pinner
379 writePinner runtime.Pinner
380 }
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395 func (fd *FD) setOffset(off int64) {
396 fd.offset = off
397 }
398
399
400 func (fd *FD) addOffset(off int) {
401 fd.offset += int64(off)
402 }
403
404
405
406 func (fd *FD) pollable() bool {
407 return fd.pd.pollable() && !fd.disassociated.Load()
408 }
409
410
411 type fileKind byte
412
413 const (
414 kindNet fileKind = iota
415 kindFile
416 kindConsole
417 kindPipe
418 )
419
420
421
422
423
424
425
426 func (fd *FD) Init(net string, pollable bool) error {
427 if initErr != nil {
428 return initErr
429 }
430
431 switch net {
432 case "file":
433 fd.kind = kindFile
434 case "console":
435 fd.kind = kindConsole
436 case "pipe":
437 fd.kind = kindPipe
438 default:
439
440 fd.kind = kindNet
441 }
442 fd.isFile = fd.kind != kindNet
443 fd.isBlocking = !pollable
444
445 if !pollable {
446 return nil
447 }
448
449
450
451
452
453 fd.waitOnSuccess = true
454
455
456
457
458 err := fd.pd.init(fd)
459 if err != nil {
460 return err
461 }
462
463
464
465
466 modes := uint8(syscall.FILE_SKIP_SET_EVENT_ON_HANDLE)
467 if canSkipCompletionPortOnSuccess(fd.Sysfd, fd.kind == kindNet) {
468 modes |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
469 }
470 if syscall.SetFileCompletionNotificationModes(fd.Sysfd, modes) == nil {
471 if modes&syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS != 0 {
472 fd.waitOnSuccess = false
473 }
474 }
475 return nil
476 }
477
478
479
480
481 func (fd *FD) DisassociateIOCP() error {
482 if err := fd.incref(); err != nil {
483 return err
484 }
485 defer fd.decref()
486
487 if fd.isBlocking || !fd.pollable() {
488
489 return nil
490 }
491
492 info := windows.FILE_COMPLETION_INFORMATION{}
493 if err := windows.NtSetInformationFile(fd.Sysfd, &windows.IO_STATUS_BLOCK{}, unsafe.Pointer(&info), uint32(unsafe.Sizeof(info)), windows.FileReplaceCompletionInformation); err != nil {
494 return err
495 }
496 fd.disassociated.Store(true)
497
498
499 return nil
500 }
501
502 func (fd *FD) destroy() error {
503 if fd.Sysfd == syscall.InvalidHandle {
504 return syscall.EINVAL
505 }
506
507
508 fd.pd.close()
509 var err error
510 switch fd.kind {
511 case kindNet:
512
513 err = CloseFunc(fd.Sysfd)
514 default:
515 err = syscall.CloseHandle(fd.Sysfd)
516 }
517 fd.Sysfd = syscall.InvalidHandle
518 runtime_Semrelease(&fd.csema)
519 return err
520 }
521
522
523
524 func (fd *FD) Close() error {
525 if !fd.fdmu.increfAndClose() {
526 return errClosing(fd.isFile)
527 }
528
529 if fd.kind == kindPipe {
530 syscall.CancelIoEx(fd.Sysfd, nil)
531 }
532
533 fd.pd.evict()
534 err := fd.decref()
535
536
537 runtime_Semacquire(&fd.csema)
538 return err
539 }
540
541
542
543
544 const maxRW = 1 << 30
545
546
547 func (fd *FD) Read(buf []byte) (int, error) {
548 if fd.kind == kindFile {
549 if err := fd.readWriteLock(); err != nil {
550 return 0, err
551 }
552 defer fd.readWriteUnlock()
553 } else {
554 if err := fd.readLock(); err != nil {
555 return 0, err
556 }
557 defer fd.readUnlock()
558 }
559
560 if len(buf) > maxRW {
561 buf = buf[:maxRW]
562 }
563
564 var n int
565 var err error
566 switch fd.kind {
567 case kindConsole:
568 n, err = fd.readConsole(buf)
569 case kindFile, kindPipe:
570 n, err = fd.execIO('r', func(o *operation) (qty uint32, err error) {
571 err = syscall.ReadFile(fd.Sysfd, buf, &qty, fd.overlapped(o))
572 return qty, err
573 }, buf)
574 fd.addOffset(n)
575 switch err {
576 case syscall.ERROR_HANDLE_EOF:
577 err = io.EOF
578 case syscall.ERROR_BROKEN_PIPE:
579
580 if fd.kind == kindPipe {
581 err = io.EOF
582 }
583 }
584 case kindNet:
585 n, err = fd.execIO('r', func(o *operation) (qty uint32, err error) {
586 var flags uint32
587 err = syscall.WSARecv(fd.Sysfd, newWsaBuf(buf), 1, &qty, &flags, &o.o, nil)
588 return qty, err
589 }, buf)
590 if race.Enabled {
591 race.Acquire(unsafe.Pointer(&ioSync))
592 }
593 }
594 if len(buf) != 0 {
595 err = fd.eofError(n, err)
596 }
597 return n, err
598 }
599
600 var ReadConsole = syscall.ReadConsole
601
602
603
604
605 func (fd *FD) readConsole(b []byte) (int, error) {
606 if len(b) == 0 {
607 return 0, nil
608 }
609
610 if fd.readuint16 == nil {
611
612
613
614 fd.readuint16 = make([]uint16, 0, 10000)
615 fd.readbyte = make([]byte, 0, 4*cap(fd.readuint16))
616 }
617
618 for fd.readbyteOffset >= len(fd.readbyte) {
619 n := cap(fd.readuint16) - len(fd.readuint16)
620 if n > len(b) {
621 n = len(b)
622 }
623 var nw uint32
624 err := ReadConsole(fd.Sysfd, &fd.readuint16[:len(fd.readuint16)+1][len(fd.readuint16)], uint32(n), &nw, nil)
625 if err != nil {
626 return 0, err
627 }
628 uint16s := fd.readuint16[:len(fd.readuint16)+int(nw)]
629 fd.readuint16 = fd.readuint16[:0]
630 buf := fd.readbyte[:0]
631 for i := 0; i < len(uint16s); i++ {
632 r := rune(uint16s[i])
633 if utf16.IsSurrogate(r) {
634 if i+1 == len(uint16s) {
635 if nw > 0 {
636
637 fd.readuint16 = fd.readuint16[:1]
638 fd.readuint16[0] = uint16(r)
639 break
640 }
641 r = utf8.RuneError
642 } else {
643 r = utf16.DecodeRune(r, rune(uint16s[i+1]))
644 if r != utf8.RuneError {
645 i++
646 }
647 }
648 }
649 buf = utf8.AppendRune(buf, r)
650 }
651 fd.readbyte = buf
652 fd.readbyteOffset = 0
653 if nw == 0 {
654 break
655 }
656 }
657
658 src := fd.readbyte[fd.readbyteOffset:]
659 var i int
660 for i = 0; i < len(src) && i < len(b); i++ {
661 x := src[i]
662 if x == 0x1A {
663 if i == 0 {
664 fd.readbyteOffset++
665 }
666 break
667 }
668 b[i] = x
669 }
670 fd.readbyteOffset += i
671 return i, nil
672 }
673
674
675 func (fd *FD) Pread(buf []byte, off int64) (int, error) {
676 if fd.kind == kindPipe {
677
678 return 0, syscall.ESPIPE
679 }
680
681 if err := fd.readWriteLock(); err != nil {
682 return 0, err
683 }
684 defer fd.readWriteUnlock()
685
686 if len(buf) > maxRW {
687 buf = buf[:maxRW]
688 }
689
690 n, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
691
692
693
694
695
696 if fd.isBlocking {
697 curoffset, err := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent)
698 if err != nil {
699 return 0, err
700 }
701 defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart)
702 }
703 o.setOffset(off)
704
705 err = syscall.ReadFile(fd.Sysfd, buf, &qty, &o.o)
706 return qty, err
707 }, buf)
708 if err == syscall.ERROR_HANDLE_EOF {
709 err = io.EOF
710 }
711 if len(buf) != 0 {
712 err = fd.eofError(n, err)
713 }
714 return n, err
715 }
716
717
718 func (fd *FD) ReadFrom(buf []byte) (int, syscall.Sockaddr, error) {
719 if len(buf) == 0 {
720 return 0, nil, nil
721 }
722 if len(buf) > maxRW {
723 buf = buf[:maxRW]
724 }
725 if err := fd.readLock(); err != nil {
726 return 0, nil, err
727 }
728 defer fd.readUnlock()
729
730 rsa := wsaRsaPool.Get().(*syscall.RawSockaddrAny)
731 defer wsaRsaPool.Put(rsa)
732 n, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
733 rsan := int32(unsafe.Sizeof(*rsa))
734 var flags uint32
735 err = syscall.WSARecvFrom(fd.Sysfd, newWsaBuf(buf), 1, &qty, &flags, rsa, &rsan, &o.o, nil)
736 return qty, err
737 }, buf)
738 err = fd.eofError(n, err)
739 if err != nil {
740 return n, nil, err
741 }
742 sa, _ := rsa.Sockaddr()
743 return n, sa, nil
744 }
745
746
747 func (fd *FD) ReadFromInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) {
748 if len(buf) == 0 {
749 return 0, nil
750 }
751 if len(buf) > maxRW {
752 buf = buf[:maxRW]
753 }
754 if err := fd.readLock(); err != nil {
755 return 0, err
756 }
757 defer fd.readUnlock()
758
759 rsa := wsaRsaPool.Get().(*syscall.RawSockaddrAny)
760 defer wsaRsaPool.Put(rsa)
761 n, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
762 rsan := int32(unsafe.Sizeof(*rsa))
763 var flags uint32
764 err = syscall.WSARecvFrom(fd.Sysfd, newWsaBuf(buf), 1, &qty, &flags, rsa, &rsan, &o.o, nil)
765 return qty, err
766 }, buf)
767 err = fd.eofError(n, err)
768 if err != nil {
769 return n, err
770 }
771 rawToSockaddrInet4(rsa, sa4)
772 return n, err
773 }
774
775
776 func (fd *FD) ReadFromInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) {
777 if len(buf) == 0 {
778 return 0, nil
779 }
780 if len(buf) > maxRW {
781 buf = buf[:maxRW]
782 }
783 if err := fd.readLock(); err != nil {
784 return 0, err
785 }
786 defer fd.readUnlock()
787
788 rsa := wsaRsaPool.Get().(*syscall.RawSockaddrAny)
789 defer wsaRsaPool.Put(rsa)
790 n, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
791 rsan := int32(unsafe.Sizeof(*rsa))
792 var flags uint32
793 err = syscall.WSARecvFrom(fd.Sysfd, newWsaBuf(buf), 1, &qty, &flags, rsa, &rsan, &o.o, nil)
794 return qty, err
795 }, buf)
796 err = fd.eofError(n, err)
797 if err != nil {
798 return n, err
799 }
800 rawToSockaddrInet6(rsa, sa6)
801 return n, err
802 }
803
804
805 func (fd *FD) Write(buf []byte) (int, error) {
806 if fd.kind == kindFile {
807 if err := fd.readWriteLock(); err != nil {
808 return 0, err
809 }
810 defer fd.readWriteUnlock()
811 } else {
812 if err := fd.writeLock(); err != nil {
813 return 0, err
814 }
815 defer fd.writeUnlock()
816 }
817
818 var ntotal int
819 for {
820 max := len(buf)
821 if max-ntotal > maxRW {
822 max = ntotal + maxRW
823 }
824 b := buf[ntotal:max]
825 var n int
826 var err error
827 switch fd.kind {
828 case kindConsole:
829 n, err = fd.writeConsole(b)
830 case kindPipe, kindFile:
831 n, err = fd.execIO('w', func(o *operation) (qty uint32, err error) {
832 err = syscall.WriteFile(fd.Sysfd, b, &qty, fd.overlapped(o))
833 return qty, err
834 }, b)
835 fd.addOffset(n)
836 case kindNet:
837 if race.Enabled {
838 race.ReleaseMerge(unsafe.Pointer(&ioSync))
839 }
840 n, err = fd.execIO('w', func(o *operation) (qty uint32, err error) {
841 err = syscall.WSASend(fd.Sysfd, newWsaBuf(b), 1, &qty, 0, &o.o, nil)
842 return qty, err
843 }, b)
844 }
845 ntotal += n
846 if ntotal == len(buf) || err != nil {
847 return ntotal, err
848 }
849 if n == 0 {
850 return ntotal, io.ErrUnexpectedEOF
851 }
852 }
853 }
854
855
856
857 func (fd *FD) writeConsole(b []byte) (int, error) {
858 n := len(b)
859 runes := make([]rune, 0, 256)
860 if len(fd.lastbits) > 0 {
861 b = append(fd.lastbits, b...)
862 fd.lastbits = nil
863
864 }
865 for len(b) >= utf8.UTFMax || utf8.FullRune(b) {
866 r, l := utf8.DecodeRune(b)
867 runes = append(runes, r)
868 b = b[l:]
869 }
870 if len(b) > 0 {
871 fd.lastbits = make([]byte, len(b))
872 copy(fd.lastbits, b)
873 }
874
875
876
877 const maxWrite = 16000
878 for len(runes) > 0 {
879 m := len(runes)
880 if m > maxWrite {
881 m = maxWrite
882 }
883 chunk := runes[:m]
884 runes = runes[m:]
885 uint16s := utf16.Encode(chunk)
886 for len(uint16s) > 0 {
887 var written uint32
888 err := syscall.WriteConsole(fd.Sysfd, &uint16s[0], uint32(len(uint16s)), &written, nil)
889 if err != nil {
890 return 0, err
891 }
892 uint16s = uint16s[written:]
893 }
894 }
895 return n, nil
896 }
897
898
899 func (fd *FD) Pwrite(buf []byte, off int64) (int, error) {
900 if fd.kind == kindPipe {
901
902 return 0, syscall.ESPIPE
903 }
904
905 if err := fd.readWriteLock(); err != nil {
906 return 0, err
907 }
908 defer fd.readWriteUnlock()
909
910 var ntotal int
911 for {
912 max := len(buf)
913 if max-ntotal > maxRW {
914 max = ntotal + maxRW
915 }
916 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
917
918
919
920
921
922 if fd.isBlocking {
923 curoffset, err := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent)
924 if err != nil {
925 return 0, err
926 }
927 defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart)
928 }
929 o.setOffset(off + int64(ntotal))
930
931 err = syscall.WriteFile(fd.Sysfd, buf[ntotal:max], &qty, &o.o)
932 return qty, err
933 }, buf[ntotal:max])
934 if n > 0 {
935 ntotal += n
936 }
937 if ntotal == len(buf) || err != nil {
938 return ntotal, err
939 }
940 if n == 0 {
941 return ntotal, io.ErrUnexpectedEOF
942 }
943 }
944 }
945
946
947 func (fd *FD) Writev(buf *[][]byte) (int64, error) {
948 if len(*buf) == 0 {
949 return 0, nil
950 }
951 if err := fd.writeLock(); err != nil {
952 return 0, err
953 }
954 defer fd.writeUnlock()
955 if race.Enabled {
956 race.ReleaseMerge(unsafe.Pointer(&ioSync))
957 }
958 bufs := newWSABufs(buf)
959 defer freeWSABufs(bufs)
960 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
961 err = syscall.WSASend(fd.Sysfd, &(*bufs)[0], uint32(len(*bufs)), &qty, 0, &o.o, nil)
962 return qty, err
963 }, nil)
964 TestHookDidWritev(n)
965 consume(buf, int64(n))
966 return int64(n), err
967 }
968
969
970 func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) {
971 if err := fd.writeLock(); err != nil {
972 return 0, err
973 }
974 defer fd.writeUnlock()
975
976 if len(buf) == 0 {
977
978 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
979 err = syscall.WSASendto(fd.Sysfd, &syscall.WSABuf{}, 1, &qty, 0, sa, &o.o, nil)
980 return qty, err
981 }, nil)
982 return n, err
983 }
984
985 ntotal := 0
986 for len(buf) > 0 {
987 b := buf
988 if len(b) > maxRW {
989 b = b[:maxRW]
990 }
991 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
992 err = syscall.WSASendto(fd.Sysfd, newWsaBuf(b), 1, &qty, 0, sa, &o.o, nil)
993 return qty, err
994 }, b)
995 ntotal += int(n)
996 if err != nil {
997 return ntotal, err
998 }
999 buf = buf[n:]
1000 }
1001 return ntotal, nil
1002 }
1003
1004
1005 func (fd *FD) WriteToInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) {
1006 if err := fd.writeLock(); err != nil {
1007 return 0, err
1008 }
1009 defer fd.writeUnlock()
1010
1011 if len(buf) == 0 {
1012
1013 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1014 err = windows.WSASendtoInet4(fd.Sysfd, &syscall.WSABuf{}, 1, &qty, 0, sa4, &o.o, nil)
1015 return qty, err
1016 }, nil)
1017 return n, err
1018 }
1019
1020 ntotal := 0
1021 for len(buf) > 0 {
1022 b := buf
1023 if len(b) > maxRW {
1024 b = b[:maxRW]
1025 }
1026 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1027 err = windows.WSASendtoInet4(fd.Sysfd, newWsaBuf(b), 1, &qty, 0, sa4, &o.o, nil)
1028 return qty, err
1029 }, b)
1030 ntotal += int(n)
1031 if err != nil {
1032 return ntotal, err
1033 }
1034 buf = buf[n:]
1035 }
1036 return ntotal, nil
1037 }
1038
1039
1040 func (fd *FD) WriteToInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) {
1041 if err := fd.writeLock(); err != nil {
1042 return 0, err
1043 }
1044 defer fd.writeUnlock()
1045
1046 if len(buf) == 0 {
1047
1048 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1049 err = windows.WSASendtoInet6(fd.Sysfd, &syscall.WSABuf{}, 1, &qty, 0, sa6, &o.o, nil)
1050 return qty, err
1051 }, nil)
1052 return n, err
1053 }
1054
1055 ntotal := 0
1056 for len(buf) > 0 {
1057 b := buf
1058 if len(b) > maxRW {
1059 b = b[:maxRW]
1060 }
1061 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1062 err = windows.WSASendtoInet6(fd.Sysfd, newWsaBuf(b), 1, &qty, 0, sa6, &o.o, nil)
1063 return qty, err
1064 }, b)
1065 ntotal += int(n)
1066 if err != nil {
1067 return ntotal, err
1068 }
1069 buf = buf[n:]
1070 }
1071 return ntotal, nil
1072 }
1073
1074
1075
1076
1077 func (fd *FD) ConnectEx(ra syscall.Sockaddr) error {
1078 _, err := fd.execIO('w', func(o *operation) (uint32, error) {
1079 return 0, ConnectExFunc(fd.Sysfd, ra, nil, 0, nil, &o.o)
1080 }, nil)
1081 return err
1082 }
1083
1084 func (fd *FD) acceptOne(s syscall.Handle, rawsa []syscall.RawSockaddrAny) (string, error) {
1085
1086 rsan := uint32(unsafe.Sizeof(rawsa[0]))
1087 _, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
1088 err = AcceptFunc(fd.Sysfd, s, (*byte)(unsafe.Pointer(&rawsa[0])), 0, rsan, rsan, &qty, &o.o)
1089 return qty, err
1090
1091 }, nil)
1092 if err != nil {
1093 CloseFunc(s)
1094 return "acceptex", err
1095 }
1096
1097
1098 err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.Sysfd)), int32(unsafe.Sizeof(fd.Sysfd)))
1099 if err != nil {
1100 CloseFunc(s)
1101 return "setsockopt", err
1102 }
1103
1104 return "", nil
1105 }
1106
1107
1108
1109 func (fd *FD) Accept(sysSocket func() (syscall.Handle, error)) (syscall.Handle, []syscall.RawSockaddrAny, uint32, string, error) {
1110 if err := fd.readLock(); err != nil {
1111 return syscall.InvalidHandle, nil, 0, "", err
1112 }
1113 defer fd.readUnlock()
1114
1115 var rawsa [2]syscall.RawSockaddrAny
1116 for {
1117 s, err := sysSocket()
1118 if err != nil {
1119 return syscall.InvalidHandle, nil, 0, "", err
1120 }
1121
1122 errcall, err := fd.acceptOne(s, rawsa[:])
1123 if err == nil {
1124 return s, rawsa[:], uint32(unsafe.Sizeof(rawsa[0])), "", nil
1125 }
1126
1127
1128
1129
1130
1131
1132 errno, ok := err.(syscall.Errno)
1133 if !ok {
1134 return syscall.InvalidHandle, nil, 0, errcall, err
1135 }
1136 switch errno {
1137 case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET:
1138
1139 default:
1140 return syscall.InvalidHandle, nil, 0, errcall, err
1141 }
1142 }
1143 }
1144
1145
1146 func (fd *FD) Seek(offset int64, whence int) (int64, error) {
1147 if fd.kind == kindPipe {
1148 return 0, syscall.ESPIPE
1149 }
1150 if err := fd.readWriteLock(); err != nil {
1151 return 0, err
1152 }
1153 defer fd.readWriteUnlock()
1154
1155 if !fd.isBlocking {
1156
1157
1158 var newOffset int64
1159 switch whence {
1160 case io.SeekStart:
1161 newOffset = offset
1162 case io.SeekCurrent:
1163 newOffset = fd.offset + offset
1164 case io.SeekEnd:
1165 var size int64
1166 if err := windows.GetFileSizeEx(fd.Sysfd, &size); err != nil {
1167 return 0, err
1168 }
1169 newOffset = size + offset
1170 default:
1171 return 0, windows.ERROR_INVALID_PARAMETER
1172 }
1173 if newOffset < 0 {
1174 return 0, windows.ERROR_NEGATIVE_SEEK
1175 }
1176 fd.setOffset(newOffset)
1177 return newOffset, nil
1178 }
1179 n, err := syscall.Seek(fd.Sysfd, offset, whence)
1180 fd.setOffset(n)
1181 return n, err
1182 }
1183
1184
1185 func (fd *FD) Fchmod(mode uint32) error {
1186 if err := fd.incref(); err != nil {
1187 return err
1188 }
1189 defer fd.decref()
1190
1191 var d syscall.ByHandleFileInformation
1192 if err := syscall.GetFileInformationByHandle(fd.Sysfd, &d); err != nil {
1193 return err
1194 }
1195 attrs := d.FileAttributes
1196 if mode&syscall.S_IWRITE != 0 {
1197 attrs &^= syscall.FILE_ATTRIBUTE_READONLY
1198 } else {
1199 attrs |= syscall.FILE_ATTRIBUTE_READONLY
1200 }
1201 if attrs == d.FileAttributes {
1202 return nil
1203 }
1204
1205 var du windows.FILE_BASIC_INFO
1206 du.FileAttributes = attrs
1207 return windows.SetFileInformationByHandle(fd.Sysfd, windows.FileBasicInfo, unsafe.Pointer(&du), uint32(unsafe.Sizeof(du)))
1208 }
1209
1210
1211 func (fd *FD) Fchdir() error {
1212 if err := fd.incref(); err != nil {
1213 return err
1214 }
1215 defer fd.decref()
1216 return syscall.Fchdir(fd.Sysfd)
1217 }
1218
1219
1220 func (fd *FD) GetFileType() (uint32, error) {
1221 if err := fd.incref(); err != nil {
1222 return 0, err
1223 }
1224 defer fd.decref()
1225 return syscall.GetFileType(fd.Sysfd)
1226 }
1227
1228
1229 func (fd *FD) GetFileInformationByHandle(data *syscall.ByHandleFileInformation) error {
1230 if err := fd.incref(); err != nil {
1231 return err
1232 }
1233 defer fd.decref()
1234 return syscall.GetFileInformationByHandle(fd.Sysfd, data)
1235 }
1236
1237
1238 func (fd *FD) RawRead(f func(uintptr) bool) error {
1239 if err := fd.readLock(); err != nil {
1240 return err
1241 }
1242 defer fd.readUnlock()
1243 for {
1244 if f(uintptr(fd.Sysfd)) {
1245 return nil
1246 }
1247
1248
1249
1250 _, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
1251 var flags uint32
1252 if !fd.IsStream {
1253 flags |= windows.MSG_PEEK
1254 }
1255 err = syscall.WSARecv(fd.Sysfd, &syscall.WSABuf{}, 1, &qty, &flags, &o.o, nil)
1256 return qty, err
1257 }, nil)
1258 if err == windows.WSAEMSGSIZE {
1259
1260 } else if err != nil {
1261 return err
1262 }
1263 }
1264 }
1265
1266
1267 func (fd *FD) RawWrite(f func(uintptr) bool) error {
1268 if err := fd.writeLock(); err != nil {
1269 return err
1270 }
1271 defer fd.writeUnlock()
1272
1273 if f(uintptr(fd.Sysfd)) {
1274 return nil
1275 }
1276
1277
1278 return syscall.EWINDOWS
1279 }
1280
1281 func sockaddrInet4ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) int32 {
1282 *rsa = syscall.RawSockaddrAny{}
1283 raw := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
1284 raw.Family = syscall.AF_INET
1285 p := (*[2]byte)(unsafe.Pointer(&raw.Port))
1286 p[0] = byte(sa.Port >> 8)
1287 p[1] = byte(sa.Port)
1288 raw.Addr = sa.Addr
1289 return int32(unsafe.Sizeof(*raw))
1290 }
1291
1292 func sockaddrInet6ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) int32 {
1293 *rsa = syscall.RawSockaddrAny{}
1294 raw := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
1295 raw.Family = syscall.AF_INET6
1296 p := (*[2]byte)(unsafe.Pointer(&raw.Port))
1297 p[0] = byte(sa.Port >> 8)
1298 p[1] = byte(sa.Port)
1299 raw.Scope_id = sa.ZoneId
1300 raw.Addr = sa.Addr
1301 return int32(unsafe.Sizeof(*raw))
1302 }
1303
1304 func rawToSockaddrInet4(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) {
1305 pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
1306 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1307 sa.Port = int(p[0])<<8 + int(p[1])
1308 sa.Addr = pp.Addr
1309 }
1310
1311 func rawToSockaddrInet6(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) {
1312 pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
1313 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1314 sa.Port = int(p[0])<<8 + int(p[1])
1315 sa.ZoneId = pp.Scope_id
1316 sa.Addr = pp.Addr
1317 }
1318
1319 func sockaddrToRaw(rsa *syscall.RawSockaddrAny, sa syscall.Sockaddr) (int32, error) {
1320 switch sa := sa.(type) {
1321 case *syscall.SockaddrInet4:
1322 sz := sockaddrInet4ToRaw(rsa, sa)
1323 return sz, nil
1324 case *syscall.SockaddrInet6:
1325 sz := sockaddrInet6ToRaw(rsa, sa)
1326 return sz, nil
1327 default:
1328 return 0, syscall.EWINDOWS
1329 }
1330 }
1331
1332
1333 func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.Sockaddr, error) {
1334 if err := fd.readLock(); err != nil {
1335 return 0, 0, 0, nil, err
1336 }
1337 defer fd.readUnlock()
1338
1339 if len(p) > maxRW {
1340 p = p[:maxRW]
1341 }
1342
1343 msg := newWSAMsg(p, oob, flags, true)
1344 defer freeWSAMsg(msg)
1345 n, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
1346 err = windows.WSARecvMsg(fd.Sysfd, msg, &qty, &o.o, nil)
1347 return qty, err
1348 }, nil)
1349 err = fd.eofError(n, err)
1350 var sa syscall.Sockaddr
1351 if err == nil {
1352 sa, err = msg.Name.Sockaddr()
1353 }
1354 return n, int(msg.Control.Len), int(msg.Flags), sa, err
1355 }
1356
1357
1358 func (fd *FD) ReadMsgInet4(p []byte, oob []byte, flags int, sa4 *syscall.SockaddrInet4) (int, int, int, error) {
1359 if err := fd.readLock(); err != nil {
1360 return 0, 0, 0, err
1361 }
1362 defer fd.readUnlock()
1363
1364 if len(p) > maxRW {
1365 p = p[:maxRW]
1366 }
1367
1368 msg := newWSAMsg(p, oob, flags, true)
1369 defer freeWSAMsg(msg)
1370 n, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
1371 err = windows.WSARecvMsg(fd.Sysfd, msg, &qty, &o.o, nil)
1372 return qty, err
1373 }, nil)
1374 err = fd.eofError(n, err)
1375 if err == nil {
1376 rawToSockaddrInet4(msg.Name, sa4)
1377 }
1378 return n, int(msg.Control.Len), int(msg.Flags), err
1379 }
1380
1381
1382 func (fd *FD) ReadMsgInet6(p []byte, oob []byte, flags int, sa6 *syscall.SockaddrInet6) (int, int, int, error) {
1383 if err := fd.readLock(); err != nil {
1384 return 0, 0, 0, err
1385 }
1386 defer fd.readUnlock()
1387
1388 if len(p) > maxRW {
1389 p = p[:maxRW]
1390 }
1391
1392 msg := newWSAMsg(p, oob, flags, true)
1393 defer freeWSAMsg(msg)
1394 n, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
1395 err = windows.WSARecvMsg(fd.Sysfd, msg, &qty, &o.o, nil)
1396 return qty, err
1397 }, nil)
1398 err = fd.eofError(n, err)
1399 if err == nil {
1400 rawToSockaddrInet6(msg.Name, sa6)
1401 }
1402 return n, int(msg.Control.Len), int(msg.Flags), err
1403 }
1404
1405
1406 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
1407 if len(p) > maxRW {
1408 return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1409 }
1410
1411 if err := fd.writeLock(); err != nil {
1412 return 0, 0, err
1413 }
1414 defer fd.writeUnlock()
1415
1416 msg := newWSAMsg(p, oob, 0, sa != nil)
1417 defer freeWSAMsg(msg)
1418 if sa != nil {
1419 var err error
1420 msg.Namelen, err = sockaddrToRaw(msg.Name, sa)
1421 if err != nil {
1422 return 0, 0, err
1423 }
1424 }
1425 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1426 err = windows.WSASendMsg(fd.Sysfd, msg, 0, nil, &o.o, nil)
1427 return qty, err
1428 }, nil)
1429 return n, int(msg.Control.Len), err
1430 }
1431
1432
1433 func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (int, int, error) {
1434 if len(p) > maxRW {
1435 return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1436 }
1437
1438 if err := fd.writeLock(); err != nil {
1439 return 0, 0, err
1440 }
1441 defer fd.writeUnlock()
1442
1443 msg := newWSAMsg(p, oob, 0, sa != nil)
1444 defer freeWSAMsg(msg)
1445 if sa != nil {
1446 msg.Namelen = sockaddrInet4ToRaw(msg.Name, sa)
1447 }
1448 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1449 err = windows.WSASendMsg(fd.Sysfd, msg, 0, nil, &o.o, nil)
1450 return qty, err
1451 }, nil)
1452 return n, int(msg.Control.Len), err
1453 }
1454
1455
1456 func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (int, int, error) {
1457 if len(p) > maxRW {
1458 return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1459 }
1460
1461 if err := fd.writeLock(); err != nil {
1462 return 0, 0, err
1463 }
1464 defer fd.writeUnlock()
1465
1466 msg := newWSAMsg(p, oob, 0, sa != nil)
1467 defer freeWSAMsg(msg)
1468 if sa != nil {
1469 msg.Namelen = sockaddrInet6ToRaw(msg.Name, sa)
1470 }
1471 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1472 err = windows.WSASendMsg(fd.Sysfd, msg, 0, nil, &o.o, nil)
1473 return qty, err
1474 }, nil)
1475 return n, int(msg.Control.Len), err
1476 }
1477
1478 func DupCloseOnExec(fd int) (int, string, error) {
1479 proc, err := syscall.GetCurrentProcess()
1480 if err != nil {
1481 return 0, "GetCurrentProcess", err
1482 }
1483
1484 var nfd syscall.Handle
1485 const inherit = false
1486 if err := syscall.DuplicateHandle(proc, syscall.Handle(fd), proc, &nfd, 0, inherit, syscall.DUPLICATE_SAME_ACCESS); err != nil {
1487 return 0, "DuplicateHandle", err
1488 }
1489 return int(nfd), "", nil
1490 }
1491
View as plain text