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