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