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