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