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 n, err := syscall.Seek(fd.Sysfd, offset, whence)
1110 fd.setOffset(n)
1111 return n, err
1112 }
1113
1114
1115 func (fd *FD) Fchmod(mode uint32) error {
1116 if err := fd.incref(); err != nil {
1117 return err
1118 }
1119 defer fd.decref()
1120
1121 var d syscall.ByHandleFileInformation
1122 if err := syscall.GetFileInformationByHandle(fd.Sysfd, &d); err != nil {
1123 return err
1124 }
1125 attrs := d.FileAttributes
1126 if mode&syscall.S_IWRITE != 0 {
1127 attrs &^= syscall.FILE_ATTRIBUTE_READONLY
1128 } else {
1129 attrs |= syscall.FILE_ATTRIBUTE_READONLY
1130 }
1131 if attrs == d.FileAttributes {
1132 return nil
1133 }
1134
1135 var du windows.FILE_BASIC_INFO
1136 du.FileAttributes = attrs
1137 return windows.SetFileInformationByHandle(fd.Sysfd, windows.FileBasicInfo, unsafe.Pointer(&du), uint32(unsafe.Sizeof(du)))
1138 }
1139
1140
1141 func (fd *FD) Fchdir() error {
1142 if err := fd.incref(); err != nil {
1143 return err
1144 }
1145 defer fd.decref()
1146 return syscall.Fchdir(fd.Sysfd)
1147 }
1148
1149
1150 func (fd *FD) GetFileType() (uint32, error) {
1151 if err := fd.incref(); err != nil {
1152 return 0, err
1153 }
1154 defer fd.decref()
1155 return syscall.GetFileType(fd.Sysfd)
1156 }
1157
1158
1159 func (fd *FD) GetFileInformationByHandle(data *syscall.ByHandleFileInformation) error {
1160 if err := fd.incref(); err != nil {
1161 return err
1162 }
1163 defer fd.decref()
1164 return syscall.GetFileInformationByHandle(fd.Sysfd, data)
1165 }
1166
1167
1168 func (fd *FD) RawRead(f func(uintptr) bool) error {
1169 if err := fd.readLock(); err != nil {
1170 return err
1171 }
1172 defer fd.readUnlock()
1173 for {
1174 if f(uintptr(fd.Sysfd)) {
1175 return nil
1176 }
1177
1178
1179
1180 o := &fd.rop
1181 o.InitBuf(nil)
1182 _, err := execIO(o, func(o *operation) error {
1183 if !fd.IsStream {
1184 o.flags |= windows.MSG_PEEK
1185 }
1186 return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
1187 })
1188 if err == windows.WSAEMSGSIZE {
1189
1190 } else if err != nil {
1191 return err
1192 }
1193 }
1194 }
1195
1196
1197 func (fd *FD) RawWrite(f func(uintptr) bool) error {
1198 if err := fd.writeLock(); err != nil {
1199 return err
1200 }
1201 defer fd.writeUnlock()
1202
1203 if f(uintptr(fd.Sysfd)) {
1204 return nil
1205 }
1206
1207
1208 return syscall.EWINDOWS
1209 }
1210
1211 func sockaddrInet4ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) int32 {
1212 *rsa = syscall.RawSockaddrAny{}
1213 raw := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
1214 raw.Family = syscall.AF_INET
1215 p := (*[2]byte)(unsafe.Pointer(&raw.Port))
1216 p[0] = byte(sa.Port >> 8)
1217 p[1] = byte(sa.Port)
1218 raw.Addr = sa.Addr
1219 return int32(unsafe.Sizeof(*raw))
1220 }
1221
1222 func sockaddrInet6ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) int32 {
1223 *rsa = syscall.RawSockaddrAny{}
1224 raw := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
1225 raw.Family = syscall.AF_INET6
1226 p := (*[2]byte)(unsafe.Pointer(&raw.Port))
1227 p[0] = byte(sa.Port >> 8)
1228 p[1] = byte(sa.Port)
1229 raw.Scope_id = sa.ZoneId
1230 raw.Addr = sa.Addr
1231 return int32(unsafe.Sizeof(*raw))
1232 }
1233
1234 func rawToSockaddrInet4(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) {
1235 pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
1236 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1237 sa.Port = int(p[0])<<8 + int(p[1])
1238 sa.Addr = pp.Addr
1239 }
1240
1241 func rawToSockaddrInet6(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) {
1242 pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
1243 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
1244 sa.Port = int(p[0])<<8 + int(p[1])
1245 sa.ZoneId = pp.Scope_id
1246 sa.Addr = pp.Addr
1247 }
1248
1249 func sockaddrToRaw(rsa *syscall.RawSockaddrAny, sa syscall.Sockaddr) (int32, error) {
1250 switch sa := sa.(type) {
1251 case *syscall.SockaddrInet4:
1252 sz := sockaddrInet4ToRaw(rsa, sa)
1253 return sz, nil
1254 case *syscall.SockaddrInet6:
1255 sz := sockaddrInet6ToRaw(rsa, sa)
1256 return sz, nil
1257 default:
1258 return 0, syscall.EWINDOWS
1259 }
1260 }
1261
1262
1263 func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.Sockaddr, error) {
1264 if err := fd.readLock(); err != nil {
1265 return 0, 0, 0, nil, err
1266 }
1267 defer fd.readUnlock()
1268
1269 if len(p) > maxRW {
1270 p = p[:maxRW]
1271 }
1272
1273 o := &fd.rop
1274 o.InitMsg(p, oob)
1275 if o.rsa == nil {
1276 o.rsa = new(syscall.RawSockaddrAny)
1277 }
1278 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1279 o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
1280 o.msg.Flags = uint32(flags)
1281 n, err := execIO(o, func(o *operation) error {
1282 return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
1283 })
1284 err = fd.eofError(n, err)
1285 var sa syscall.Sockaddr
1286 if err == nil {
1287 sa, err = o.rsa.Sockaddr()
1288 }
1289 return n, int(o.msg.Control.Len), int(o.msg.Flags), sa, err
1290 }
1291
1292
1293 func (fd *FD) ReadMsgInet4(p []byte, oob []byte, flags int, sa4 *syscall.SockaddrInet4) (int, int, int, error) {
1294 if err := fd.readLock(); err != nil {
1295 return 0, 0, 0, err
1296 }
1297 defer fd.readUnlock()
1298
1299 if len(p) > maxRW {
1300 p = p[:maxRW]
1301 }
1302
1303 o := &fd.rop
1304 o.InitMsg(p, oob)
1305 if o.rsa == nil {
1306 o.rsa = new(syscall.RawSockaddrAny)
1307 }
1308 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1309 o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
1310 o.msg.Flags = uint32(flags)
1311 n, err := execIO(o, func(o *operation) error {
1312 return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
1313 })
1314 err = fd.eofError(n, err)
1315 if err == nil {
1316 rawToSockaddrInet4(o.rsa, sa4)
1317 }
1318 return n, int(o.msg.Control.Len), int(o.msg.Flags), err
1319 }
1320
1321
1322 func (fd *FD) ReadMsgInet6(p []byte, oob []byte, flags int, sa6 *syscall.SockaddrInet6) (int, int, int, error) {
1323 if err := fd.readLock(); err != nil {
1324 return 0, 0, 0, err
1325 }
1326 defer fd.readUnlock()
1327
1328 if len(p) > maxRW {
1329 p = p[:maxRW]
1330 }
1331
1332 o := &fd.rop
1333 o.InitMsg(p, oob)
1334 if o.rsa == nil {
1335 o.rsa = new(syscall.RawSockaddrAny)
1336 }
1337 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1338 o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
1339 o.msg.Flags = uint32(flags)
1340 n, err := execIO(o, func(o *operation) error {
1341 return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
1342 })
1343 err = fd.eofError(n, err)
1344 if err == nil {
1345 rawToSockaddrInet6(o.rsa, sa6)
1346 }
1347 return n, int(o.msg.Control.Len), int(o.msg.Flags), err
1348 }
1349
1350
1351 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
1352 if len(p) > maxRW {
1353 return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1354 }
1355
1356 if err := fd.writeLock(); err != nil {
1357 return 0, 0, err
1358 }
1359 defer fd.writeUnlock()
1360
1361 o := &fd.wop
1362 o.InitMsg(p, oob)
1363 if sa != nil {
1364 if o.rsa == nil {
1365 o.rsa = new(syscall.RawSockaddrAny)
1366 }
1367 len, err := sockaddrToRaw(o.rsa, sa)
1368 if err != nil {
1369 return 0, 0, err
1370 }
1371 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1372 o.msg.Namelen = len
1373 }
1374 n, err := execIO(o, func(o *operation) error {
1375 return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
1376 })
1377 return n, int(o.msg.Control.Len), err
1378 }
1379
1380
1381 func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (int, int, error) {
1382 if len(p) > maxRW {
1383 return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1384 }
1385
1386 if err := fd.writeLock(); err != nil {
1387 return 0, 0, err
1388 }
1389 defer fd.writeUnlock()
1390
1391 o := &fd.wop
1392 o.InitMsg(p, oob)
1393 if o.rsa == nil {
1394 o.rsa = new(syscall.RawSockaddrAny)
1395 }
1396 len := sockaddrInet4ToRaw(o.rsa, sa)
1397 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1398 o.msg.Namelen = len
1399 n, err := execIO(o, func(o *operation) error {
1400 return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
1401 })
1402 return n, int(o.msg.Control.Len), err
1403 }
1404
1405
1406 func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (int, int, error) {
1407 if len(p) > maxRW {
1408 return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
1409 }
1410
1411 if err := fd.writeLock(); err != nil {
1412 return 0, 0, err
1413 }
1414 defer fd.writeUnlock()
1415
1416 o := &fd.wop
1417 o.InitMsg(p, oob)
1418 if o.rsa == nil {
1419 o.rsa = new(syscall.RawSockaddrAny)
1420 }
1421 len := sockaddrInet6ToRaw(o.rsa, sa)
1422 o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
1423 o.msg.Namelen = len
1424 n, err := execIO(o, func(o *operation) error {
1425 return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
1426 })
1427 return n, int(o.msg.Control.Len), err
1428 }
1429
1430 func DupCloseOnExec(fd int) (int, string, error) {
1431 proc, err := syscall.GetCurrentProcess()
1432 if err != nil {
1433 return 0, "GetCurrentProcess", err
1434 }
1435
1436 var nfd syscall.Handle
1437 const inherit = false
1438 if err := syscall.DuplicateHandle(proc, syscall.Handle(fd), proc, &nfd, 0, inherit, syscall.DUPLICATE_SAME_ACCESS); err != nil {
1439 return 0, "DuplicateHandle", err
1440 }
1441 return int(nfd), "", nil
1442 }
1443
View as plain text