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