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