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