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