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