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