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 curoffset, err := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent)
640 if err != nil {
641 return 0, err
642 }
643 defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart)
644 defer fd.setOffset(curoffset)
645 o := &fd.rop
646 o.InitBuf(b)
647 fd.setOffset(off)
648 n, err := execIO(o, func(o *operation) error {
649 return syscall.ReadFile(o.fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &o.qty, &o.o)
650 })
651 if err == syscall.ERROR_HANDLE_EOF {
652 err = io.EOF
653 }
654 if len(b) != 0 {
655 err = fd.eofError(n, err)
656 }
657 return n, err
658 }
659
660
661 func (fd *FD) ReadFrom(buf []byte) (int, syscall.Sockaddr, error) {
662 if len(buf) == 0 {
663 return 0, nil, nil
664 }
665 if len(buf) > maxRW {
666 buf = buf[:maxRW]
667 }
668 if err := fd.readLock(); err != nil {
669 return 0, nil, err
670 }
671 defer fd.readUnlock()
672 o := &fd.rop
673 o.InitBuf(buf)
674 n, err := execIO(o, func(o *operation) error {
675 if o.rsa == nil {
676 o.rsa = new(syscall.RawSockaddrAny)
677 }
678 o.rsan = int32(unsafe.Sizeof(*o.rsa))
679 return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
680 })
681 err = fd.eofError(n, err)
682 if err != nil {
683 return n, nil, err
684 }
685 sa, _ := o.rsa.Sockaddr()
686 return n, sa, nil
687 }
688
689
690 func (fd *FD) ReadFromInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) {
691 if len(buf) == 0 {
692 return 0, nil
693 }
694 if len(buf) > maxRW {
695 buf = buf[:maxRW]
696 }
697 if err := fd.readLock(); err != nil {
698 return 0, err
699 }
700 defer fd.readUnlock()
701 o := &fd.rop
702 o.InitBuf(buf)
703 n, err := execIO(o, func(o *operation) error {
704 if o.rsa == nil {
705 o.rsa = new(syscall.RawSockaddrAny)
706 }
707 o.rsan = int32(unsafe.Sizeof(*o.rsa))
708 return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
709 })
710 err = fd.eofError(n, err)
711 if err != nil {
712 return n, err
713 }
714 rawToSockaddrInet4(o.rsa, sa4)
715 return n, err
716 }
717
718
719 func (fd *FD) ReadFromInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) {
720 if len(buf) == 0 {
721 return 0, nil
722 }
723 if len(buf) > maxRW {
724 buf = buf[:maxRW]
725 }
726 if err := fd.readLock(); err != nil {
727 return 0, err
728 }
729 defer fd.readUnlock()
730 o := &fd.rop
731 o.InitBuf(buf)
732 n, err := execIO(o, func(o *operation) error {
733 if o.rsa == nil {
734 o.rsa = new(syscall.RawSockaddrAny)
735 }
736 o.rsan = int32(unsafe.Sizeof(*o.rsa))
737 return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
738 })
739 err = fd.eofError(n, err)
740 if err != nil {
741 return n, err
742 }
743 rawToSockaddrInet6(o.rsa, sa6)
744 return n, err
745 }
746
747
748 func (fd *FD) Write(buf []byte) (int, error) {
749 if err := fd.writeLock(); err != nil {
750 return 0, err
751 }
752 defer fd.writeUnlock()
753 if fd.kind == kindFile {
754 fd.l.Lock()
755 defer fd.l.Unlock()
756 }
757
758 var ntotal int
759 for {
760 max := len(buf)
761 if max-ntotal > maxRW {
762 max = ntotal + maxRW
763 }
764 b := buf[ntotal:max]
765 var n int
766 var err error
767 switch fd.kind {
768 case kindConsole:
769 n, err = fd.writeConsole(b)
770 case kindPipe, kindFile:
771 o := &fd.wop
772 o.InitBuf(b)
773 n, err = execIO(o, func(o *operation) error {
774 return syscall.WriteFile(o.fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &o.qty, o.overlapped())
775 })
776 fd.addOffset(n)
777 case kindNet:
778 if race.Enabled {
779 race.ReleaseMerge(unsafe.Pointer(&ioSync))
780 }
781 o := &fd.wop
782 o.InitBuf(b)
783 n, err = execIO(o, func(o *operation) error {
784 return syscall.WSASend(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil)
785 })
786 }
787 ntotal += n
788 if ntotal == len(buf) || err != nil {
789 return ntotal, err
790 }
791 if n == 0 {
792 return ntotal, io.ErrUnexpectedEOF
793 }
794 }
795 }
796
797
798
799 func (fd *FD) writeConsole(b []byte) (int, error) {
800 n := len(b)
801 runes := make([]rune, 0, 256)
802 if len(fd.lastbits) > 0 {
803 b = append(fd.lastbits, b...)
804 fd.lastbits = nil
805
806 }
807 for len(b) >= utf8.UTFMax || utf8.FullRune(b) {
808 r, l := utf8.DecodeRune(b)
809 runes = append(runes, r)
810 b = b[l:]
811 }
812 if len(b) > 0 {
813 fd.lastbits = make([]byte, len(b))
814 copy(fd.lastbits, b)
815 }
816
817
818
819 const maxWrite = 16000
820 for len(runes) > 0 {
821 m := len(runes)
822 if m > maxWrite {
823 m = maxWrite
824 }
825 chunk := runes[:m]
826 runes = runes[m:]
827 uint16s := utf16.Encode(chunk)
828 for len(uint16s) > 0 {
829 var written uint32
830 err := syscall.WriteConsole(fd.Sysfd, &uint16s[0], uint32(len(uint16s)), &written, nil)
831 if err != nil {
832 return 0, err
833 }
834 uint16s = uint16s[written:]
835 }
836 }
837 return n, nil
838 }
839
840
841 func (fd *FD) Pwrite(buf []byte, off int64) (int, error) {
842 if fd.kind == kindPipe {
843
844 return 0, syscall.ESPIPE
845 }
846
847
848 if err := fd.incref(); err != nil {
849 return 0, err
850 }
851 defer fd.decref()
852
853 fd.l.Lock()
854 defer fd.l.Unlock()
855 curoffset, err := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent)
856 if err != nil {
857 return 0, err
858 }
859 defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart)
860 defer fd.setOffset(curoffset)
861
862 var ntotal int
863 for {
864 max := len(buf)
865 if max-ntotal > maxRW {
866 max = ntotal + maxRW
867 }
868 b := buf[ntotal:max]
869 o := &fd.wop
870 o.InitBuf(b)
871 fd.setOffset(off + int64(ntotal))
872 n, err := execIO(o, func(o *operation) error {
873 return syscall.WriteFile(o.fd.Sysfd, unsafe.Slice(o.buf.Buf, o.buf.Len), &o.qty, &o.o)
874 })
875 if n > 0 {
876 ntotal += n
877 }
878 if ntotal == len(buf) || err != nil {
879 return ntotal, err
880 }
881 if n == 0 {
882 return ntotal, io.ErrUnexpectedEOF
883 }
884 }
885 }
886
887
888 func (fd *FD) Writev(buf *[][]byte) (int64, error) {
889 if len(*buf) == 0 {
890 return 0, nil
891 }
892 if err := fd.writeLock(); err != nil {
893 return 0, err
894 }
895 defer fd.writeUnlock()
896 if race.Enabled {
897 race.ReleaseMerge(unsafe.Pointer(&ioSync))
898 }
899 o := &fd.wop
900 o.InitBufs(buf)
901 n, err := execIO(o, func(o *operation) error {
902 return syscall.WSASend(o.fd.Sysfd, &o.bufs[0], uint32(len(o.bufs)), &o.qty, 0, &o.o, nil)
903 })
904 o.ClearBufs()
905 TestHookDidWritev(n)
906 consume(buf, int64(n))
907 return int64(n), err
908 }
909
910
911 func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) {
912 if err := fd.writeLock(); err != nil {
913 return 0, err
914 }
915 defer fd.writeUnlock()
916
917 if len(buf) == 0 {
918
919 o := &fd.wop
920 o.InitBuf(buf)
921 o.sa = sa
922 n, err := execIO(o, func(o *operation) error {
923 return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
924 })
925 return n, err
926 }
927
928 ntotal := 0
929 for len(buf) > 0 {
930 b := buf
931 if len(b) > maxRW {
932 b = b[:maxRW]
933 }
934 o := &fd.wop
935 o.InitBuf(b)
936 o.sa = sa
937 n, err := execIO(o, func(o *operation) error {
938 return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
939 })
940 ntotal += int(n)
941 if err != nil {
942 return ntotal, err
943 }
944 buf = buf[n:]
945 }
946 return ntotal, nil
947 }
948
949
950 func (fd *FD) WriteToInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) {
951 if err := fd.writeLock(); err != nil {
952 return 0, err
953 }
954 defer fd.writeUnlock()
955
956 if len(buf) == 0 {
957
958 o := &fd.wop
959 o.InitBuf(buf)
960 n, err := execIO(o, func(o *operation) error {
961 return windows.WSASendtoInet4(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa4, &o.o, nil)
962 })
963 return n, err
964 }
965
966 ntotal := 0
967 for len(buf) > 0 {
968 b := buf
969 if len(b) > maxRW {
970 b = b[:maxRW]
971 }
972 o := &fd.wop
973 o.InitBuf(b)
974 n, err := execIO(o, func(o *operation) error {
975 return windows.WSASendtoInet4(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa4, &o.o, nil)
976 })
977 ntotal += int(n)
978 if err != nil {
979 return ntotal, err
980 }
981 buf = buf[n:]
982 }
983 return ntotal, nil
984 }
985
986
987 func (fd *FD) WriteToInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) {
988 if err := fd.writeLock(); err != nil {
989 return 0, err
990 }
991 defer fd.writeUnlock()
992
993 if len(buf) == 0 {
994
995 o := &fd.wop
996 o.InitBuf(buf)
997 n, err := execIO(o, func(o *operation) error {
998 return windows.WSASendtoInet6(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa6, &o.o, nil)
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 := execIO(o, func(o *operation) error {
1012 return windows.WSASendtoInet6(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa6, &o.o, nil)
1013 })
1014 ntotal += int(n)
1015 if err != nil {
1016 return ntotal, err
1017 }
1018 buf = buf[n:]
1019 }
1020 return ntotal, nil
1021 }
1022
1023
1024
1025
1026 func (fd *FD) ConnectEx(ra syscall.Sockaddr) error {
1027 o := &fd.wop
1028 o.sa = ra
1029 _, err := execIO(o, func(o *operation) error {
1030 return ConnectExFunc(o.fd.Sysfd, o.sa, 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 o.handle = s
1038 o.rsan = int32(unsafe.Sizeof(rawsa[0]))
1039 _, err := execIO(o, func(o *operation) error {
1040 return AcceptFunc(o.fd.Sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o)
1041 })
1042 if err != nil {
1043 CloseFunc(s)
1044 return "acceptex", err
1045 }
1046
1047
1048 err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.Sysfd)), int32(unsafe.Sizeof(fd.Sysfd)))
1049 if err != nil {
1050 CloseFunc(s)
1051 return "setsockopt", err
1052 }
1053
1054 return "", nil
1055 }
1056
1057
1058
1059 func (fd *FD) Accept(sysSocket func() (syscall.Handle, error)) (syscall.Handle, []syscall.RawSockaddrAny, uint32, string, error) {
1060 if err := fd.readLock(); err != nil {
1061 return syscall.InvalidHandle, nil, 0, "", err
1062 }
1063 defer fd.readUnlock()
1064
1065 o := &fd.rop
1066 var rawsa [2]syscall.RawSockaddrAny
1067 for {
1068 s, err := sysSocket()
1069 if err != nil {
1070 return syscall.InvalidHandle, nil, 0, "", err
1071 }
1072
1073 errcall, err := fd.acceptOne(s, rawsa[:], o)
1074 if err == nil {
1075 return s, rawsa[:], uint32(o.rsan), "", nil
1076 }
1077
1078
1079
1080
1081
1082
1083 errno, ok := err.(syscall.Errno)
1084 if !ok {
1085 return syscall.InvalidHandle, nil, 0, errcall, err
1086 }
1087 switch errno {
1088 case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET:
1089
1090 default:
1091 return syscall.InvalidHandle, nil, 0, errcall, err
1092 }
1093 }
1094 }
1095
1096
1097 func (fd *FD) Seek(offset int64, whence int) (int64, error) {
1098 if fd.kind == kindPipe {
1099 return 0, syscall.ESPIPE
1100 }
1101 if err := fd.incref(); err != nil {
1102 return 0, err
1103 }
1104 defer fd.decref()
1105
1106 fd.l.Lock()
1107 defer fd.l.Unlock()
1108
1109 if !fd.isBlocking && whence == io.SeekCurrent {
1110
1111
1112
1113 offset += fd.offset
1114 }
1115 n, err := syscall.Seek(fd.Sysfd, offset, whence)
1116 fd.setOffset(n)
1117 return n, err
1118 }
1119
1120
1121 func (fd *FD) Fchmod(mode uint32) error {
1122 if err := fd.incref(); err != nil {
1123 return err
1124 }
1125 defer fd.decref()
1126
1127 var d syscall.ByHandleFileInformation
1128 if err := syscall.GetFileInformationByHandle(fd.Sysfd, &d); err != nil {
1129 return err
1130 }
1131 attrs := d.FileAttributes
1132 if mode&syscall.S_IWRITE != 0 {
1133 attrs &^= syscall.FILE_ATTRIBUTE_READONLY
1134 } else {
1135 attrs |= syscall.FILE_ATTRIBUTE_READONLY
1136 }
1137 if attrs == d.FileAttributes {
1138 return nil
1139 }
1140
1141 var du windows.FILE_BASIC_INFO
1142 du.FileAttributes = attrs
1143 return windows.SetFileInformationByHandle(fd.Sysfd, windows.FileBasicInfo, unsafe.Pointer(&du), uint32(unsafe.Sizeof(du)))
1144 }
1145
1146
1147 func (fd *FD) Fchdir() error {
1148 if err := fd.incref(); err != nil {
1149 return err
1150 }
1151 defer fd.decref()
1152 return syscall.Fchdir(fd.Sysfd)
1153 }
1154
1155
1156 func (fd *FD) GetFileType() (uint32, error) {
1157 if err := fd.incref(); err != nil {
1158 return 0, err
1159 }
1160 defer fd.decref()
1161 return syscall.GetFileType(fd.Sysfd)
1162 }
1163
1164
1165 func (fd *FD) GetFileInformationByHandle(data *syscall.ByHandleFileInformation) error {
1166 if err := fd.incref(); err != nil {
1167 return err
1168 }
1169 defer fd.decref()
1170 return syscall.GetFileInformationByHandle(fd.Sysfd, data)
1171 }
1172
1173
1174 func (fd *FD) RawRead(f func(uintptr) bool) error {
1175 if err := fd.readLock(); err != nil {
1176 return err
1177 }
1178 defer fd.readUnlock()
1179 for {
1180 if f(uintptr(fd.Sysfd)) {
1181 return nil
1182 }
1183
1184
1185
1186 o := &fd.rop
1187 o.InitBuf(nil)
1188 _, err := execIO(o, func(o *operation) error {
1189 if !fd.IsStream {
1190 o.flags |= windows.MSG_PEEK
1191 }
1192 return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
1193 })
1194 if err == windows.WSAEMSGSIZE {
1195
1196 } else if err != nil {
1197 return err
1198 }
1199 }
1200 }
1201
1202
1203 func (fd *FD) RawWrite(f func(uintptr) bool) error {
1204 if err := fd.writeLock(); err != nil {
1205 return err
1206 }
1207 defer fd.writeUnlock()
1208
1209 if f(uintptr(fd.Sysfd)) {
1210 return nil
1211 }
1212
1213
1214 return syscall.EWINDOWS
1215 }
1216
1217 func sockaddrInet4ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) int32 {
1218 *rsa = syscall.RawSockaddrAny{}
1219 raw := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
1220 raw.Family = syscall.AF_INET
1221 p := (*[2]byte)(unsafe.Pointer(&raw.Port))
1222 p[0] = byte(sa.Port >> 8)
1223 p[1] = byte(sa.Port)
1224 raw.Addr = sa.Addr
1225 return int32(unsafe.Sizeof(*raw))
1226 }
1227
1228 func sockaddrInet6ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) int32 {
1229 *rsa = syscall.RawSockaddrAny{}
1230 raw := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
1231 raw.Family = syscall.AF_INET6
1232 p := (*[2]byte)(unsafe.Pointer(&raw.Port))
1233 p[0] = byte(sa.Port >> 8)
1234 p[1] = byte(sa.Port)
1235 raw.Scope_id = sa.ZoneId
1236 raw.Addr = sa.Addr
1237 return int32(unsafe.Sizeof(*raw))
1238 }
1239
1240 func rawToSockaddrInet4(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) {
1241 pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
1242 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1243 sa.Port = int(p[0])<<8 + int(p[1])
1244 sa.Addr = pp.Addr
1245 }
1246
1247 func rawToSockaddrInet6(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) {
1248 pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
1249 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1250 sa.Port = int(p[0])<<8 + int(p[1])
1251 sa.ZoneId = pp.Scope_id
1252 sa.Addr = pp.Addr
1253 }
1254
1255 func sockaddrToRaw(rsa *syscall.RawSockaddrAny, sa syscall.Sockaddr) (int32, error) {
1256 switch sa := sa.(type) {
1257 case *syscall.SockaddrInet4:
1258 sz := sockaddrInet4ToRaw(rsa, sa)
1259 return sz, nil
1260 case *syscall.SockaddrInet6:
1261 sz := sockaddrInet6ToRaw(rsa, sa)
1262 return sz, nil
1263 default:
1264 return 0, syscall.EWINDOWS
1265 }
1266 }
1267
1268
1269 func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.Sockaddr, error) {
1270 if err := fd.readLock(); err != nil {
1271 return 0, 0, 0, nil, err
1272 }
1273 defer fd.readUnlock()
1274
1275 if len(p) > maxRW {
1276 p = p[:maxRW]
1277 }
1278
1279 o := &fd.rop
1280 o.InitMsg(p, oob)
1281 if o.rsa == nil {
1282 o.rsa = new(syscall.RawSockaddrAny)
1283 }
1284 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1285 o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
1286 o.msg.Flags = uint32(flags)
1287 n, err := execIO(o, func(o *operation) error {
1288 return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
1289 })
1290 err = fd.eofError(n, err)
1291 var sa syscall.Sockaddr
1292 if err == nil {
1293 sa, err = o.rsa.Sockaddr()
1294 }
1295 return n, int(o.msg.Control.Len), int(o.msg.Flags), sa, err
1296 }
1297
1298
1299 func (fd *FD) ReadMsgInet4(p []byte, oob []byte, flags int, sa4 *syscall.SockaddrInet4) (int, int, int, error) {
1300 if err := fd.readLock(); err != nil {
1301 return 0, 0, 0, err
1302 }
1303 defer fd.readUnlock()
1304
1305 if len(p) > maxRW {
1306 p = p[:maxRW]
1307 }
1308
1309 o := &fd.rop
1310 o.InitMsg(p, oob)
1311 if o.rsa == nil {
1312 o.rsa = new(syscall.RawSockaddrAny)
1313 }
1314 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1315 o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
1316 o.msg.Flags = uint32(flags)
1317 n, err := execIO(o, func(o *operation) error {
1318 return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
1319 })
1320 err = fd.eofError(n, err)
1321 if err == nil {
1322 rawToSockaddrInet4(o.rsa, sa4)
1323 }
1324 return n, int(o.msg.Control.Len), int(o.msg.Flags), err
1325 }
1326
1327
1328 func (fd *FD) ReadMsgInet6(p []byte, oob []byte, flags int, sa6 *syscall.SockaddrInet6) (int, int, int, error) {
1329 if err := fd.readLock(); err != nil {
1330 return 0, 0, 0, err
1331 }
1332 defer fd.readUnlock()
1333
1334 if len(p) > maxRW {
1335 p = p[:maxRW]
1336 }
1337
1338 o := &fd.rop
1339 o.InitMsg(p, oob)
1340 if o.rsa == nil {
1341 o.rsa = new(syscall.RawSockaddrAny)
1342 }
1343 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1344 o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
1345 o.msg.Flags = uint32(flags)
1346 n, err := execIO(o, func(o *operation) error {
1347 return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
1348 })
1349 err = fd.eofError(n, err)
1350 if err == nil {
1351 rawToSockaddrInet6(o.rsa, sa6)
1352 }
1353 return n, int(o.msg.Control.Len), int(o.msg.Flags), err
1354 }
1355
1356
1357 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
1358 if len(p) > maxRW {
1359 return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1360 }
1361
1362 if err := fd.writeLock(); err != nil {
1363 return 0, 0, err
1364 }
1365 defer fd.writeUnlock()
1366
1367 o := &fd.wop
1368 o.InitMsg(p, oob)
1369 if sa != nil {
1370 if o.rsa == nil {
1371 o.rsa = new(syscall.RawSockaddrAny)
1372 }
1373 len, err := sockaddrToRaw(o.rsa, sa)
1374 if err != nil {
1375 return 0, 0, err
1376 }
1377 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1378 o.msg.Namelen = len
1379 }
1380 n, err := execIO(o, func(o *operation) error {
1381 return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
1382 })
1383 return n, int(o.msg.Control.Len), err
1384 }
1385
1386
1387 func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (int, int, error) {
1388 if len(p) > maxRW {
1389 return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1390 }
1391
1392 if err := fd.writeLock(); err != nil {
1393 return 0, 0, err
1394 }
1395 defer fd.writeUnlock()
1396
1397 o := &fd.wop
1398 o.InitMsg(p, oob)
1399 if o.rsa == nil {
1400 o.rsa = new(syscall.RawSockaddrAny)
1401 }
1402 len := sockaddrInet4ToRaw(o.rsa, sa)
1403 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1404 o.msg.Namelen = len
1405 n, err := execIO(o, func(o *operation) error {
1406 return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
1407 })
1408 return n, int(o.msg.Control.Len), err
1409 }
1410
1411
1412 func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (int, int, error) {
1413 if len(p) > maxRW {
1414 return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1415 }
1416
1417 if err := fd.writeLock(); err != nil {
1418 return 0, 0, err
1419 }
1420 defer fd.writeUnlock()
1421
1422 o := &fd.wop
1423 o.InitMsg(p, oob)
1424 if o.rsa == nil {
1425 o.rsa = new(syscall.RawSockaddrAny)
1426 }
1427 len := sockaddrInet6ToRaw(o.rsa, sa)
1428 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1429 o.msg.Namelen = len
1430 n, err := execIO(o, func(o *operation) error {
1431 return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
1432 })
1433 return n, int(o.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