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