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