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 isFile bool
382
383
384 kind fileKind
385
386
387 isBlocking bool
388
389
390 associated bool
391
392
393
394 readPinner runtime.Pinner
395 writePinner runtime.Pinner
396 }
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411 func (fd *FD) setOffset(off int64) {
412 fd.offset = off
413 }
414
415
416 func (fd *FD) addOffset(off int) {
417 fd.offset += int64(off)
418 }
419
420
421 type fileKind byte
422
423 const (
424 kindNet fileKind = iota
425 kindFile
426 kindConsole
427 kindPipe
428 )
429
430
431
432
433
434
435
436 func (fd *FD) Init(net string, pollable bool) error {
437 if initErr != nil {
438 return initErr
439 }
440
441 switch net {
442 case "file":
443 fd.kind = kindFile
444 case "console":
445 fd.kind = kindConsole
446 case "pipe":
447 fd.kind = kindPipe
448 default:
449
450 fd.kind = kindNet
451 }
452 fd.isFile = fd.kind != kindNet
453 fd.isBlocking = !pollable
454
455 if !pollable {
456 return nil
457 }
458
459
460
461
462
463 fd.waitOnSuccess = true
464
465
466
467
468 err := fd.pd.init(fd)
469 if err != nil {
470 return err
471 }
472 fd.associated = true
473
474
475
476
477 modes := uint8(syscall.FILE_SKIP_SET_EVENT_ON_HANDLE)
478 if canSkipCompletionPortOnSuccess(fd.Sysfd, fd.kind == kindNet) {
479 modes |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
480 }
481 if syscall.SetFileCompletionNotificationModes(fd.Sysfd, modes) == nil {
482 if modes&syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS != 0 {
483 fd.waitOnSuccess = false
484 }
485 }
486 return nil
487 }
488
489
490
491
492 func (fd *FD) DisassociateIOCP() error {
493
494
495
496
497 if ok, err := fd.tryReadWriteLock(); err != nil || !ok {
498 if err == nil {
499 err = errors.New("can't disassociate the handle while there is in-progress I/O")
500 }
501 return err
502 }
503 defer fd.readWriteUnlock()
504
505 if !fd.associated {
506
507 return nil
508 }
509
510 info := windows.FILE_COMPLETION_INFORMATION{}
511 if err := windows.NtSetInformationFile(fd.Sysfd, &windows.IO_STATUS_BLOCK{}, unsafe.Pointer(&info), uint32(unsafe.Sizeof(info)), windows.FileReplaceCompletionInformation); err != nil {
512 return err
513 }
514
515 fd.associated = false
516
517
518 return nil
519 }
520
521 func (fd *FD) destroy() error {
522 if fd.Sysfd == syscall.InvalidHandle {
523 return syscall.EINVAL
524 }
525
526
527 fd.pd.close()
528 var err error
529 switch fd.kind {
530 case kindNet:
531
532 err = CloseFunc(fd.Sysfd)
533 default:
534 err = syscall.CloseHandle(fd.Sysfd)
535 }
536 fd.Sysfd = syscall.InvalidHandle
537 runtime_Semrelease(&fd.csema)
538 return err
539 }
540
541
542
543 func (fd *FD) Close() error {
544 if !fd.fdmu.increfAndClose() {
545 return errClosing(fd.isFile)
546 }
547
548 if fd.kind == kindPipe {
549 syscall.CancelIoEx(fd.Sysfd, nil)
550 }
551
552 fd.pd.evict()
553 err := fd.decref()
554
555
556 runtime_Semacquire(&fd.csema)
557 return err
558 }
559
560
561
562
563 const maxRW = 1 << 30
564
565 func pinPtrsFromBuf(buf []byte) []any {
566 if len(buf) == 0 {
567 return nil
568 }
569 return []any{unsafe.SliceData(buf)}
570 }
571
572
573 func (fd *FD) Read(buf []byte) (int, error) {
574 if fd.kind == kindFile {
575 if err := fd.readWriteLock(); err != nil {
576 return 0, err
577 }
578 defer fd.readWriteUnlock()
579 } else {
580 if err := fd.readLock(); err != nil {
581 return 0, err
582 }
583 defer fd.readUnlock()
584 }
585
586 if len(buf) > maxRW {
587 buf = buf[:maxRW]
588 }
589
590 var n int
591 var err error
592 switch fd.kind {
593 case kindConsole:
594 n, err = fd.readConsole(buf)
595 case kindFile, kindPipe:
596 n, err = fd.execIO('r', func(o *operation) (qty uint32, err error) {
597 err = syscall.ReadFile(fd.Sysfd, buf, &qty, fd.overlapped(o))
598 return qty, err
599 }, pinPtrsFromBuf(buf)...)
600 fd.addOffset(n)
601 switch err {
602 case syscall.ERROR_HANDLE_EOF:
603 err = io.EOF
604 case syscall.ERROR_BROKEN_PIPE:
605
606 if fd.kind == kindPipe {
607 err = io.EOF
608 }
609 }
610 case kindNet:
611 n, err = fd.execIO('r', func(o *operation) (qty uint32, err error) {
612 var flags uint32
613 err = syscall.WSARecv(fd.Sysfd, newWsaBuf(buf), 1, &qty, &flags, &o.o, nil)
614 return qty, err
615 }, pinPtrsFromBuf(buf)...)
616 if race.Enabled {
617 race.Acquire(unsafe.Pointer(&ioSync))
618 }
619 }
620 if len(buf) != 0 {
621 err = fd.eofError(n, err)
622 }
623 return n, err
624 }
625
626 var ReadConsole = syscall.ReadConsole
627
628
629
630
631 func (fd *FD) readConsole(b []byte) (int, error) {
632 if len(b) == 0 {
633 return 0, nil
634 }
635
636 if fd.readuint16 == nil {
637
638
639
640 fd.readuint16 = make([]uint16, 0, 10000)
641 fd.readbyte = make([]byte, 0, 4*cap(fd.readuint16))
642 }
643
644 for fd.readbyteOffset >= len(fd.readbyte) {
645 n := cap(fd.readuint16) - len(fd.readuint16)
646 if n > len(b) {
647 n = len(b)
648 }
649 var nw uint32
650 err := ReadConsole(fd.Sysfd, &fd.readuint16[:len(fd.readuint16)+1][len(fd.readuint16)], uint32(n), &nw, nil)
651 if err != nil {
652 return 0, err
653 }
654 uint16s := fd.readuint16[:len(fd.readuint16)+int(nw)]
655 fd.readuint16 = fd.readuint16[:0]
656 buf := fd.readbyte[:0]
657 for i := 0; i < len(uint16s); i++ {
658 r := rune(uint16s[i])
659 if utf16.IsSurrogate(r) {
660 if i+1 == len(uint16s) {
661 if nw > 0 {
662
663 fd.readuint16 = fd.readuint16[:1]
664 fd.readuint16[0] = uint16(r)
665 break
666 }
667 r = utf8.RuneError
668 } else {
669 r = utf16.DecodeRune(r, rune(uint16s[i+1]))
670 if r != utf8.RuneError {
671 i++
672 }
673 }
674 }
675 buf = utf8.AppendRune(buf, r)
676 }
677 fd.readbyte = buf
678 fd.readbyteOffset = 0
679 if nw == 0 {
680 break
681 }
682 }
683
684 src := fd.readbyte[fd.readbyteOffset:]
685 var i int
686 for i = 0; i < len(src) && i < len(b); i++ {
687 x := src[i]
688 if x == 0x1A {
689 if i == 0 {
690 fd.readbyteOffset++
691 }
692 break
693 }
694 b[i] = x
695 }
696 fd.readbyteOffset += i
697 return i, nil
698 }
699
700
701 func (fd *FD) Pread(buf []byte, off int64) (int, error) {
702 if fd.kind == kindPipe {
703
704 return 0, syscall.ESPIPE
705 }
706
707 if err := fd.readWriteLock(); err != nil {
708 return 0, err
709 }
710 defer fd.readWriteUnlock()
711
712 if len(buf) > maxRW {
713 buf = buf[:maxRW]
714 }
715
716 n, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
717
718
719
720
721
722 if fd.isBlocking {
723 curoffset, err := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent)
724 if err != nil {
725 return 0, err
726 }
727 defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart)
728 }
729 o.setOffset(off)
730
731 err = syscall.ReadFile(fd.Sysfd, buf, &qty, &o.o)
732 return qty, err
733 }, pinPtrsFromBuf(buf)...)
734 if err == syscall.ERROR_HANDLE_EOF {
735 err = io.EOF
736 }
737 if len(buf) != 0 {
738 err = fd.eofError(n, err)
739 }
740 return n, err
741 }
742
743
744 func (fd *FD) ReadFrom(buf []byte) (int, syscall.Sockaddr, error) {
745 if len(buf) == 0 {
746 return 0, nil, nil
747 }
748 if len(buf) > maxRW {
749 buf = buf[:maxRW]
750 }
751 if err := fd.readLock(); err != nil {
752 return 0, nil, err
753 }
754 defer fd.readUnlock()
755
756 rsa := newWSARsa()
757 defer wsaRsaPool.Put(rsa)
758 n, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
759 var flags uint32
760 err = syscall.WSARecvFrom(fd.Sysfd, newWsaBuf(buf), 1, &qty, &flags, &rsa.name, &rsa.namelen, &o.o, nil)
761 return qty, err
762 }, unsafe.SliceData(buf), rsa)
763 err = fd.eofError(n, err)
764 if err != nil {
765 return n, nil, err
766 }
767 sa, _ := rsa.name.Sockaddr()
768 return n, sa, nil
769 }
770
771
772 func (fd *FD) ReadFromInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) {
773 if len(buf) == 0 {
774 return 0, nil
775 }
776 if len(buf) > maxRW {
777 buf = buf[:maxRW]
778 }
779 if err := fd.readLock(); err != nil {
780 return 0, err
781 }
782 defer fd.readUnlock()
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 }, unsafe.SliceData(buf), rsa)
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 rsa := newWSARsa()
813 defer wsaRsaPool.Put(rsa)
814 n, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
815 var flags uint32
816 err = syscall.WSARecvFrom(fd.Sysfd, newWsaBuf(buf), 1, &qty, &flags, &rsa.name, &rsa.namelen, &o.o, nil)
817 return qty, err
818 }, unsafe.SliceData(buf), rsa)
819 err = fd.eofError(n, err)
820 if err != nil {
821 return n, err
822 }
823 rawToSockaddrInet6(&rsa.name, sa6)
824 return n, err
825 }
826
827
828 func (fd *FD) Write(buf []byte) (int, error) {
829 if fd.kind == kindFile {
830 if err := fd.readWriteLock(); err != nil {
831 return 0, err
832 }
833 defer fd.readWriteUnlock()
834 } else {
835 if err := fd.writeLock(); err != nil {
836 return 0, err
837 }
838 defer fd.writeUnlock()
839 }
840
841 var ntotal int
842 for {
843 max := len(buf)
844 if max-ntotal > maxRW {
845 max = ntotal + maxRW
846 }
847 b := buf[ntotal:max]
848 var n int
849 var err error
850 switch fd.kind {
851 case kindConsole:
852 n, err = fd.writeConsole(b)
853 case kindPipe, kindFile:
854 n, err = fd.execIO('w', func(o *operation) (qty uint32, err error) {
855 err = syscall.WriteFile(fd.Sysfd, b, &qty, fd.overlapped(o))
856 return qty, err
857 }, pinPtrsFromBuf(b)...)
858 fd.addOffset(n)
859 case kindNet:
860 if race.Enabled {
861 race.ReleaseMerge(unsafe.Pointer(&ioSync))
862 }
863 n, err = fd.execIO('w', func(o *operation) (qty uint32, err error) {
864 err = syscall.WSASend(fd.Sysfd, newWsaBuf(b), 1, &qty, 0, &o.o, nil)
865 return qty, err
866 }, pinPtrsFromBuf(b)...)
867 }
868 ntotal += n
869 if ntotal == len(buf) || err != nil {
870 return ntotal, err
871 }
872 if n == 0 {
873 return ntotal, io.ErrUnexpectedEOF
874 }
875 }
876 }
877
878
879
880 func (fd *FD) writeConsole(b []byte) (int, error) {
881 n := len(b)
882 runes := make([]rune, 0, 256)
883 if len(fd.lastbits) > 0 {
884 b = append(fd.lastbits, b...)
885 fd.lastbits = nil
886
887 }
888 for len(b) >= utf8.UTFMax || utf8.FullRune(b) {
889 r, l := utf8.DecodeRune(b)
890 runes = append(runes, r)
891 b = b[l:]
892 }
893 if len(b) > 0 {
894 fd.lastbits = make([]byte, len(b))
895 copy(fd.lastbits, b)
896 }
897
898
899
900 const maxWrite = 16000
901 for len(runes) > 0 {
902 m := len(runes)
903 if m > maxWrite {
904 m = maxWrite
905 }
906 chunk := runes[:m]
907 runes = runes[m:]
908 uint16s := utf16.Encode(chunk)
909 for len(uint16s) > 0 {
910 var written uint32
911 err := syscall.WriteConsole(fd.Sysfd, &uint16s[0], uint32(len(uint16s)), &written, nil)
912 if err != nil {
913 return 0, err
914 }
915 uint16s = uint16s[written:]
916 }
917 }
918 return n, nil
919 }
920
921
922 func (fd *FD) Pwrite(buf []byte, off int64) (int, error) {
923 if fd.kind == kindPipe {
924
925 return 0, syscall.ESPIPE
926 }
927
928 if err := fd.readWriteLock(); err != nil {
929 return 0, err
930 }
931 defer fd.readWriteUnlock()
932
933 var ntotal int
934 for {
935 max := len(buf)
936 if max-ntotal > maxRW {
937 max = ntotal + maxRW
938 }
939 b := buf[ntotal:max]
940 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
941
942
943
944
945
946 if fd.isBlocking {
947 curoffset, err := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent)
948 if err != nil {
949 return 0, err
950 }
951 defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart)
952 }
953 o.setOffset(off + int64(ntotal))
954
955 err = syscall.WriteFile(fd.Sysfd, b, &qty, &o.o)
956 return qty, err
957 }, pinPtrsFromBuf(b)...)
958 if n > 0 {
959 ntotal += n
960 }
961 if ntotal == len(buf) || err != nil {
962 return ntotal, err
963 }
964 if n == 0 {
965 return ntotal, io.ErrUnexpectedEOF
966 }
967 }
968 }
969
970
971 func (fd *FD) Writev(buf *[][]byte) (int64, error) {
972 if len(*buf) == 0 {
973 return 0, nil
974 }
975 if err := fd.writeLock(); err != nil {
976 return 0, err
977 }
978 defer fd.writeUnlock()
979 if race.Enabled {
980 race.ReleaseMerge(unsafe.Pointer(&ioSync))
981 }
982 bufs := newWSABufs(buf)
983 defer freeWSABufs(bufs)
984 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
985 err = syscall.WSASend(fd.Sysfd, &(*bufs)[0], uint32(len(*bufs)), &qty, 0, &o.o, nil)
986 return qty, err
987 })
988 TestHookDidWritev(n)
989 consume(buf, int64(n))
990 return int64(n), err
991 }
992
993
994 func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) {
995 if err := fd.writeLock(); err != nil {
996 return 0, err
997 }
998 defer fd.writeUnlock()
999
1000 if len(buf) == 0 {
1001
1002 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1003 err = syscall.WSASendto(fd.Sysfd, &syscall.WSABuf{}, 1, &qty, 0, sa, &o.o, nil)
1004 return qty, err
1005 })
1006 return n, err
1007 }
1008
1009 ntotal := 0
1010 for len(buf) > 0 {
1011 b := buf
1012 if len(b) > maxRW {
1013 b = b[:maxRW]
1014 }
1015 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1016 err = syscall.WSASendto(fd.Sysfd, newWsaBuf(b), 1, &qty, 0, sa, &o.o, nil)
1017 return qty, err
1018 }, unsafe.SliceData(b))
1019 ntotal += int(n)
1020 if err != nil {
1021 return ntotal, err
1022 }
1023 buf = buf[n:]
1024 }
1025 return ntotal, nil
1026 }
1027
1028
1029 func (fd *FD) WriteToInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) {
1030 if err := fd.writeLock(); err != nil {
1031 return 0, err
1032 }
1033 defer fd.writeUnlock()
1034
1035 if len(buf) == 0 {
1036
1037 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1038 err = windows.WSASendtoInet4(fd.Sysfd, &syscall.WSABuf{}, 1, &qty, 0, sa4, &o.o, nil)
1039 return qty, err
1040 })
1041 return n, err
1042 }
1043
1044 ntotal := 0
1045 for len(buf) > 0 {
1046 b := buf
1047 if len(b) > maxRW {
1048 b = b[:maxRW]
1049 }
1050 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1051 err = windows.WSASendtoInet4(fd.Sysfd, newWsaBuf(b), 1, &qty, 0, sa4, &o.o, nil)
1052 return qty, err
1053 }, unsafe.SliceData(b))
1054 ntotal += int(n)
1055 if err != nil {
1056 return ntotal, err
1057 }
1058 buf = buf[n:]
1059 }
1060 return ntotal, nil
1061 }
1062
1063
1064 func (fd *FD) WriteToInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) {
1065 if err := fd.writeLock(); err != nil {
1066 return 0, err
1067 }
1068 defer fd.writeUnlock()
1069
1070 if len(buf) == 0 {
1071
1072 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1073 err = windows.WSASendtoInet6(fd.Sysfd, &syscall.WSABuf{}, 1, &qty, 0, sa6, &o.o, nil)
1074 return qty, err
1075 })
1076 return n, err
1077 }
1078
1079 ntotal := 0
1080 for len(buf) > 0 {
1081 b := buf
1082 if len(b) > maxRW {
1083 b = b[:maxRW]
1084 }
1085 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1086 err = windows.WSASendtoInet6(fd.Sysfd, newWsaBuf(b), 1, &qty, 0, sa6, &o.o, nil)
1087 return qty, err
1088 }, unsafe.SliceData(b))
1089 ntotal += int(n)
1090 if err != nil {
1091 return ntotal, err
1092 }
1093 buf = buf[n:]
1094 }
1095 return ntotal, nil
1096 }
1097
1098
1099
1100
1101 func (fd *FD) ConnectEx(ra syscall.Sockaddr) error {
1102 _, err := fd.execIO('w', func(o *operation) (uint32, error) {
1103 return 0, ConnectExFunc(fd.Sysfd, ra, nil, 0, nil, &o.o)
1104 })
1105 return err
1106 }
1107
1108 func (fd *FD) acceptOne(s syscall.Handle, rawsa []syscall.RawSockaddrAny) (string, error) {
1109
1110 rsan := uint32(unsafe.Sizeof(rawsa[0]))
1111 _, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
1112 err = AcceptFunc(fd.Sysfd, s, (*byte)(unsafe.Pointer(&rawsa[0])), 0, rsan, rsan, &qty, &o.o)
1113 return qty, err
1114
1115 })
1116 if err != nil {
1117 CloseFunc(s)
1118 return "acceptex", err
1119 }
1120
1121
1122 err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.Sysfd)), int32(unsafe.Sizeof(fd.Sysfd)))
1123 if err != nil {
1124 CloseFunc(s)
1125 return "setsockopt", err
1126 }
1127
1128 return "", nil
1129 }
1130
1131
1132
1133 func (fd *FD) Accept(sysSocket func() (syscall.Handle, error)) (syscall.Handle, []syscall.RawSockaddrAny, uint32, string, error) {
1134 if err := fd.readLock(); err != nil {
1135 return syscall.InvalidHandle, nil, 0, "", err
1136 }
1137 defer fd.readUnlock()
1138
1139 var rawsa [2]syscall.RawSockaddrAny
1140 for {
1141 s, err := sysSocket()
1142 if err != nil {
1143 return syscall.InvalidHandle, nil, 0, "", err
1144 }
1145
1146 errcall, err := fd.acceptOne(s, rawsa[:])
1147 if err == nil {
1148 return s, rawsa[:], uint32(unsafe.Sizeof(rawsa[0])), "", nil
1149 }
1150
1151
1152
1153
1154
1155
1156 errno, ok := err.(syscall.Errno)
1157 if !ok {
1158 return syscall.InvalidHandle, nil, 0, errcall, err
1159 }
1160 switch errno {
1161 case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET:
1162
1163 default:
1164 return syscall.InvalidHandle, nil, 0, errcall, err
1165 }
1166 }
1167 }
1168
1169
1170 func (fd *FD) Seek(offset int64, whence int) (int64, error) {
1171 if fd.kind == kindPipe {
1172 return 0, syscall.ESPIPE
1173 }
1174 if err := fd.readWriteLock(); err != nil {
1175 return 0, err
1176 }
1177 defer fd.readWriteUnlock()
1178
1179 if !fd.isBlocking {
1180
1181
1182 var newOffset int64
1183 switch whence {
1184 case io.SeekStart:
1185 newOffset = offset
1186 case io.SeekCurrent:
1187 newOffset = fd.offset + offset
1188 case io.SeekEnd:
1189 var size int64
1190 if err := windows.GetFileSizeEx(fd.Sysfd, &size); err != nil {
1191 return 0, err
1192 }
1193 newOffset = size + offset
1194 default:
1195 return 0, windows.ERROR_INVALID_PARAMETER
1196 }
1197 if newOffset < 0 {
1198 return 0, windows.ERROR_NEGATIVE_SEEK
1199 }
1200 fd.setOffset(newOffset)
1201 return newOffset, nil
1202 }
1203 n, err := syscall.Seek(fd.Sysfd, offset, whence)
1204 fd.setOffset(n)
1205 return n, err
1206 }
1207
1208
1209 func (fd *FD) Fchmod(mode uint32) error {
1210 if err := fd.incref(); err != nil {
1211 return err
1212 }
1213 defer fd.decref()
1214
1215 var d syscall.ByHandleFileInformation
1216 if err := syscall.GetFileInformationByHandle(fd.Sysfd, &d); err != nil {
1217 return err
1218 }
1219 attrs := d.FileAttributes
1220 if mode&syscall.S_IWRITE != 0 {
1221 attrs &^= syscall.FILE_ATTRIBUTE_READONLY
1222 } else {
1223 attrs |= syscall.FILE_ATTRIBUTE_READONLY
1224 }
1225 if attrs == d.FileAttributes {
1226 return nil
1227 }
1228
1229 var du windows.FILE_BASIC_INFO
1230 du.FileAttributes = attrs
1231 return windows.SetFileInformationByHandle(fd.Sysfd, windows.FileBasicInfo, unsafe.Pointer(&du), uint32(unsafe.Sizeof(du)))
1232 }
1233
1234
1235 func (fd *FD) Fchdir() error {
1236 if err := fd.incref(); err != nil {
1237 return err
1238 }
1239 defer fd.decref()
1240 return syscall.Fchdir(fd.Sysfd)
1241 }
1242
1243
1244 func (fd *FD) GetFileType() (uint32, error) {
1245 if err := fd.incref(); err != nil {
1246 return 0, err
1247 }
1248 defer fd.decref()
1249 return syscall.GetFileType(fd.Sysfd)
1250 }
1251
1252
1253 func (fd *FD) GetFileInformationByHandle(data *syscall.ByHandleFileInformation) error {
1254 if err := fd.incref(); err != nil {
1255 return err
1256 }
1257 defer fd.decref()
1258 return syscall.GetFileInformationByHandle(fd.Sysfd, data)
1259 }
1260
1261
1262 func (fd *FD) RawRead(f func(uintptr) bool) error {
1263 if err := fd.readLock(); err != nil {
1264 return err
1265 }
1266 defer fd.readUnlock()
1267 for {
1268 if f(uintptr(fd.Sysfd)) {
1269 return nil
1270 }
1271
1272
1273
1274 _, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
1275 var flags uint32
1276 if !fd.IsStream {
1277 flags |= windows.MSG_PEEK
1278 }
1279 err = syscall.WSARecv(fd.Sysfd, &syscall.WSABuf{}, 1, &qty, &flags, &o.o, nil)
1280 return qty, err
1281 })
1282 if err == windows.WSAEMSGSIZE {
1283
1284 } else if err != nil {
1285 return err
1286 }
1287 }
1288 }
1289
1290
1291 func (fd *FD) RawWrite(f func(uintptr) bool) error {
1292 if err := fd.writeLock(); err != nil {
1293 return err
1294 }
1295 defer fd.writeUnlock()
1296
1297 if f(uintptr(fd.Sysfd)) {
1298 return nil
1299 }
1300
1301
1302 return syscall.EWINDOWS
1303 }
1304
1305 func sockaddrInet4ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) int32 {
1306 *rsa = syscall.RawSockaddrAny{}
1307 raw := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
1308 raw.Family = syscall.AF_INET
1309 p := (*[2]byte)(unsafe.Pointer(&raw.Port))
1310 p[0] = byte(sa.Port >> 8)
1311 p[1] = byte(sa.Port)
1312 raw.Addr = sa.Addr
1313 return int32(unsafe.Sizeof(*raw))
1314 }
1315
1316 func sockaddrInet6ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) int32 {
1317 *rsa = syscall.RawSockaddrAny{}
1318 raw := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
1319 raw.Family = syscall.AF_INET6
1320 p := (*[2]byte)(unsafe.Pointer(&raw.Port))
1321 p[0] = byte(sa.Port >> 8)
1322 p[1] = byte(sa.Port)
1323 raw.Scope_id = sa.ZoneId
1324 raw.Addr = sa.Addr
1325 return int32(unsafe.Sizeof(*raw))
1326 }
1327
1328 func rawToSockaddrInet4(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) {
1329 pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
1330 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1331 sa.Port = int(p[0])<<8 + int(p[1])
1332 sa.Addr = pp.Addr
1333 }
1334
1335 func rawToSockaddrInet6(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) {
1336 pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
1337 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1338 sa.Port = int(p[0])<<8 + int(p[1])
1339 sa.ZoneId = pp.Scope_id
1340 sa.Addr = pp.Addr
1341 }
1342
1343 func sockaddrToRaw(rsa *syscall.RawSockaddrAny, sa syscall.Sockaddr) (int32, error) {
1344 switch sa := sa.(type) {
1345 case *syscall.SockaddrInet4:
1346 sz := sockaddrInet4ToRaw(rsa, sa)
1347 return sz, nil
1348 case *syscall.SockaddrInet6:
1349 sz := sockaddrInet6ToRaw(rsa, sa)
1350 return sz, nil
1351 default:
1352 return 0, syscall.EWINDOWS
1353 }
1354 }
1355
1356
1357 func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.Sockaddr, error) {
1358 if err := fd.readLock(); err != nil {
1359 return 0, 0, 0, nil, err
1360 }
1361 defer fd.readUnlock()
1362
1363 if len(p) > maxRW {
1364 p = p[:maxRW]
1365 }
1366
1367 rsa := newWSARsa()
1368 defer wsaRsaPool.Put(rsa)
1369 msg := newWSAMsg(p, oob, flags, rsa)
1370 defer freeWSAMsg(msg)
1371 n, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
1372 err = windows.WSARecvMsg(fd.Sysfd, msg, &qty, &o.o, nil)
1373 return qty, err
1374 }, rsa, msg)
1375 err = fd.eofError(n, err)
1376 var sa syscall.Sockaddr
1377 if err == nil {
1378 sa, err = msg.Name.Sockaddr()
1379 }
1380 return n, int(msg.Control.Len), int(msg.Flags), sa, err
1381 }
1382
1383
1384 func (fd *FD) ReadMsgInet4(p []byte, oob []byte, flags int, sa4 *syscall.SockaddrInet4) (int, int, int, error) {
1385 if err := fd.readLock(); err != nil {
1386 return 0, 0, 0, err
1387 }
1388 defer fd.readUnlock()
1389
1390 if len(p) > maxRW {
1391 p = p[:maxRW]
1392 }
1393
1394 rsa := newWSARsa()
1395 defer wsaRsaPool.Put(rsa)
1396 msg := newWSAMsg(p, oob, flags, rsa)
1397 defer freeWSAMsg(msg)
1398 n, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
1399 err = windows.WSARecvMsg(fd.Sysfd, msg, &qty, &o.o, nil)
1400 return qty, err
1401 }, rsa, msg)
1402 err = fd.eofError(n, err)
1403 if err == nil {
1404 rawToSockaddrInet4(msg.Name, sa4)
1405 }
1406 return n, int(msg.Control.Len), int(msg.Flags), err
1407 }
1408
1409
1410 func (fd *FD) ReadMsgInet6(p []byte, oob []byte, flags int, sa6 *syscall.SockaddrInet6) (int, int, int, error) {
1411 if err := fd.readLock(); err != nil {
1412 return 0, 0, 0, err
1413 }
1414 defer fd.readUnlock()
1415
1416 if len(p) > maxRW {
1417 p = p[:maxRW]
1418 }
1419
1420 rsa := newWSARsa()
1421 defer wsaRsaPool.Put(rsa)
1422 msg := newWSAMsg(p, oob, flags, rsa)
1423 defer freeWSAMsg(msg)
1424 n, err := fd.execIO('r', func(o *operation) (qty uint32, err error) {
1425 err = windows.WSARecvMsg(fd.Sysfd, msg, &qty, &o.o, nil)
1426 return qty, err
1427 }, rsa, msg)
1428 err = fd.eofError(n, err)
1429 if err == nil {
1430 rawToSockaddrInet6(msg.Name, sa6)
1431 }
1432 return n, int(msg.Control.Len), int(msg.Flags), err
1433 }
1434
1435
1436 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
1437 if len(p) > maxRW {
1438 return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1439 }
1440
1441 if err := fd.writeLock(); err != nil {
1442 return 0, 0, err
1443 }
1444 defer fd.writeUnlock()
1445
1446 var rsa *wsaRsa
1447 if sa != nil {
1448 rsa = newWSARsa()
1449 defer wsaRsaPool.Put(rsa)
1450 var err error
1451 rsa.namelen, err = sockaddrToRaw(&rsa.name, sa)
1452 if err != nil {
1453 return 0, 0, err
1454 }
1455 }
1456 msg := newWSAMsg(p, oob, 0, rsa)
1457 defer freeWSAMsg(msg)
1458 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1459 err = windows.WSASendMsg(fd.Sysfd, msg, 0, nil, &o.o, nil)
1460 return qty, err
1461 }, rsa, msg)
1462 return n, int(msg.Control.Len), err
1463 }
1464
1465
1466 func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (int, int, error) {
1467 if len(p) > maxRW {
1468 return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1469 }
1470
1471 if err := fd.writeLock(); err != nil {
1472 return 0, 0, err
1473 }
1474 defer fd.writeUnlock()
1475
1476 var rsa *wsaRsa
1477 if sa != nil {
1478 rsa = newWSARsa()
1479 defer wsaRsaPool.Put(rsa)
1480 rsa.namelen = sockaddrInet4ToRaw(&rsa.name, sa)
1481 }
1482 msg := newWSAMsg(p, oob, 0, rsa)
1483 defer freeWSAMsg(msg)
1484 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1485 err = windows.WSASendMsg(fd.Sysfd, msg, 0, nil, &o.o, nil)
1486 return qty, err
1487 }, rsa, msg)
1488 return n, int(msg.Control.Len), err
1489 }
1490
1491
1492 func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (int, int, error) {
1493 if len(p) > maxRW {
1494 return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1495 }
1496
1497 if err := fd.writeLock(); err != nil {
1498 return 0, 0, err
1499 }
1500 defer fd.writeUnlock()
1501
1502 var rsa *wsaRsa
1503 if sa != nil {
1504 rsa = newWSARsa()
1505 defer wsaRsaPool.Put(rsa)
1506 rsa.namelen = sockaddrInet6ToRaw(&rsa.name, sa)
1507 }
1508 msg := newWSAMsg(p, oob, 0, rsa)
1509 defer freeWSAMsg(msg)
1510 n, err := fd.execIO('w', func(o *operation) (qty uint32, err error) {
1511 err = windows.WSASendMsg(fd.Sysfd, msg, 0, nil, &o.o, nil)
1512 return qty, err
1513 }, rsa, msg)
1514 return n, int(msg.Control.Len), err
1515 }
1516
1517 func DupCloseOnExec(fd int) (int, string, error) {
1518 proc, err := syscall.GetCurrentProcess()
1519 if err != nil {
1520 return 0, "GetCurrentProcess", err
1521 }
1522
1523 var nfd syscall.Handle
1524 const inherit = false
1525 if err := syscall.DuplicateHandle(proc, syscall.Handle(fd), proc, &nfd, 0, inherit, syscall.DUPLICATE_SAME_ACCESS); err != nil {
1526 return 0, "DuplicateHandle", err
1527 }
1528 return int(nfd), "", nil
1529 }
1530
View as plain text