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