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