1
2
3
4
5
6
7 package poll
8
9 import (
10 "internal/syscall/unix"
11 "io"
12 "sync/atomic"
13 "syscall"
14 )
15
16
17
18 type FD struct {
19
20 fdmu fdMutex
21
22
23 Sysfd int
24
25
26 pd pollDesc
27
28
29 iovecs *[]syscall.Iovec
30
31
32 csema uint32
33
34
35 isBlocking uint32
36
37
38
39 IsStream bool
40
41
42
43 ZeroReadIsEOF bool
44
45
46 isFile bool
47 }
48
49
50
51
52
53
54 func (fd *FD) Init(net string, pollable bool) error {
55
56 if net == "file" {
57 fd.isFile = true
58 }
59 if !pollable {
60 fd.isBlocking = 1
61 return nil
62 }
63 err := fd.pd.init(fd)
64 if err != nil {
65
66
67 fd.isBlocking = 1
68 }
69 return err
70 }
71
72
73
74 func (fd *FD) destroy() error {
75
76
77 fd.pd.close()
78
79
80
81
82
83
84 err := CloseFunc(fd.Sysfd)
85
86 fd.Sysfd = -1
87 runtime_Semrelease(&fd.csema)
88 return err
89 }
90
91
92
93 func (fd *FD) Close() error {
94 if !fd.fdmu.increfAndClose() {
95 return errClosing(fd.isFile)
96 }
97
98
99
100
101
102
103 fd.pd.evict()
104
105
106
107 err := fd.decref()
108
109
110
111
112
113
114
115 if fd.isBlocking == 0 {
116 runtime_Semacquire(&fd.csema)
117 }
118
119 return err
120 }
121
122
123 func (fd *FD) SetBlocking() error {
124 if err := fd.incref(); err != nil {
125 return err
126 }
127 defer fd.decref()
128
129
130
131 atomic.StoreUint32(&fd.isBlocking, 1)
132 return syscall.SetNonblock(fd.Sysfd, false)
133 }
134
135
136
137
138
139
140 const maxRW = 1 << 30
141
142
143 func (fd *FD) Read(p []byte) (int, error) {
144 if err := fd.readLock(); err != nil {
145 return 0, err
146 }
147 defer fd.readUnlock()
148 if len(p) == 0 {
149
150
151
152
153
154 return 0, nil
155 }
156 if err := fd.pd.prepareRead(fd.isFile); err != nil {
157 return 0, err
158 }
159 if fd.IsStream && len(p) > maxRW {
160 p = p[:maxRW]
161 }
162 for {
163 n, err := ignoringEINTRIO(syscall.Read, fd.Sysfd, p)
164 if err != nil {
165 n = 0
166 if err == syscall.EAGAIN && fd.pd.pollable() {
167 if err = fd.pd.waitRead(fd.isFile); err == nil {
168 continue
169 }
170 }
171 }
172 err = fd.eofError(n, err)
173 return n, err
174 }
175 }
176
177
178 func (fd *FD) Pread(p []byte, off int64) (int, error) {
179
180
181
182 if err := fd.incref(); err != nil {
183 return 0, err
184 }
185 if fd.IsStream && len(p) > maxRW {
186 p = p[:maxRW]
187 }
188 var (
189 n int
190 err error
191 )
192 for {
193 n, err = syscall.Pread(fd.Sysfd, p, off)
194 if err != syscall.EINTR {
195 break
196 }
197 }
198 if err != nil {
199 n = 0
200 }
201 fd.decref()
202 err = fd.eofError(n, err)
203 return n, err
204 }
205
206
207 func (fd *FD) ReadFrom(p []byte) (int, syscall.Sockaddr, error) {
208 if err := fd.readLock(); err != nil {
209 return 0, nil, err
210 }
211 defer fd.readUnlock()
212 if err := fd.pd.prepareRead(fd.isFile); err != nil {
213 return 0, nil, err
214 }
215 for {
216 n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0)
217 if err != nil {
218 if err == syscall.EINTR {
219 continue
220 }
221 n = 0
222 if err == syscall.EAGAIN && fd.pd.pollable() {
223 if err = fd.pd.waitRead(fd.isFile); err == nil {
224 continue
225 }
226 }
227 }
228 err = fd.eofError(n, err)
229 return n, sa, err
230 }
231 }
232
233
234 func (fd *FD) ReadFromInet4(p []byte, from *syscall.SockaddrInet4) (int, error) {
235 if err := fd.readLock(); err != nil {
236 return 0, err
237 }
238 defer fd.readUnlock()
239 if err := fd.pd.prepareRead(fd.isFile); err != nil {
240 return 0, err
241 }
242 for {
243 n, err := unix.RecvfromInet4(fd.Sysfd, p, 0, from)
244 if err != nil {
245 if err == syscall.EINTR {
246 continue
247 }
248 n = 0
249 if err == syscall.EAGAIN && fd.pd.pollable() {
250 if err = fd.pd.waitRead(fd.isFile); err == nil {
251 continue
252 }
253 }
254 }
255 err = fd.eofError(n, err)
256 return n, err
257 }
258 }
259
260
261 func (fd *FD) ReadFromInet6(p []byte, from *syscall.SockaddrInet6) (int, error) {
262 if err := fd.readLock(); err != nil {
263 return 0, err
264 }
265 defer fd.readUnlock()
266 if err := fd.pd.prepareRead(fd.isFile); err != nil {
267 return 0, err
268 }
269 for {
270 n, err := unix.RecvfromInet6(fd.Sysfd, p, 0, from)
271 if err != nil {
272 if err == syscall.EINTR {
273 continue
274 }
275 n = 0
276 if err == syscall.EAGAIN && fd.pd.pollable() {
277 if err = fd.pd.waitRead(fd.isFile); err == nil {
278 continue
279 }
280 }
281 }
282 err = fd.eofError(n, err)
283 return n, err
284 }
285 }
286
287
288 func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.Sockaddr, error) {
289 if err := fd.readLock(); err != nil {
290 return 0, 0, 0, nil, err
291 }
292 defer fd.readUnlock()
293 if err := fd.pd.prepareRead(fd.isFile); err != nil {
294 return 0, 0, 0, nil, err
295 }
296 for {
297 n, oobn, sysflags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, flags)
298 if err != nil {
299 if err == syscall.EINTR {
300 continue
301 }
302
303 if err == syscall.EAGAIN && fd.pd.pollable() {
304 if err = fd.pd.waitRead(fd.isFile); err == nil {
305 continue
306 }
307 }
308 }
309 err = fd.eofError(n, err)
310 return n, oobn, sysflags, sa, err
311 }
312 }
313
314
315 func (fd *FD) ReadMsgInet4(p []byte, oob []byte, flags int, sa4 *syscall.SockaddrInet4) (int, int, int, error) {
316 if err := fd.readLock(); err != nil {
317 return 0, 0, 0, err
318 }
319 defer fd.readUnlock()
320 if err := fd.pd.prepareRead(fd.isFile); err != nil {
321 return 0, 0, 0, err
322 }
323 for {
324 n, oobn, sysflags, err := unix.RecvmsgInet4(fd.Sysfd, p, oob, flags, sa4)
325 if err != nil {
326 if err == syscall.EINTR {
327 continue
328 }
329
330 if err == syscall.EAGAIN && fd.pd.pollable() {
331 if err = fd.pd.waitRead(fd.isFile); err == nil {
332 continue
333 }
334 }
335 }
336 err = fd.eofError(n, err)
337 return n, oobn, sysflags, err
338 }
339 }
340
341
342 func (fd *FD) ReadMsgInet6(p []byte, oob []byte, flags int, sa6 *syscall.SockaddrInet6) (int, int, int, error) {
343 if err := fd.readLock(); err != nil {
344 return 0, 0, 0, err
345 }
346 defer fd.readUnlock()
347 if err := fd.pd.prepareRead(fd.isFile); err != nil {
348 return 0, 0, 0, err
349 }
350 for {
351 n, oobn, sysflags, err := unix.RecvmsgInet6(fd.Sysfd, p, oob, flags, sa6)
352 if err != nil {
353 if err == syscall.EINTR {
354 continue
355 }
356
357 if err == syscall.EAGAIN && fd.pd.pollable() {
358 if err = fd.pd.waitRead(fd.isFile); err == nil {
359 continue
360 }
361 }
362 }
363 err = fd.eofError(n, err)
364 return n, oobn, sysflags, err
365 }
366 }
367
368
369 func (fd *FD) Write(p []byte) (int, error) {
370 if err := fd.writeLock(); err != nil {
371 return 0, err
372 }
373 defer fd.writeUnlock()
374 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
375 return 0, err
376 }
377 var nn int
378 for {
379 max := len(p)
380 if fd.IsStream && max-nn > maxRW {
381 max = nn + maxRW
382 }
383 n, err := ignoringEINTRIO(syscall.Write, fd.Sysfd, p[nn:max])
384 if n > 0 {
385 nn += n
386 }
387 if nn == len(p) {
388 return nn, err
389 }
390 if err == syscall.EAGAIN && fd.pd.pollable() {
391 if err = fd.pd.waitWrite(fd.isFile); err == nil {
392 continue
393 }
394 }
395 if err != nil {
396 return nn, err
397 }
398 if n == 0 {
399 return nn, io.ErrUnexpectedEOF
400 }
401 }
402 }
403
404
405 func (fd *FD) Pwrite(p []byte, off int64) (int, error) {
406
407
408
409 if err := fd.incref(); err != nil {
410 return 0, err
411 }
412 defer fd.decref()
413 var nn int
414 for {
415 max := len(p)
416 if fd.IsStream && max-nn > maxRW {
417 max = nn + maxRW
418 }
419 n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn))
420 if err == syscall.EINTR {
421 continue
422 }
423 if n > 0 {
424 nn += n
425 }
426 if nn == len(p) {
427 return nn, err
428 }
429 if err != nil {
430 return nn, err
431 }
432 if n == 0 {
433 return nn, io.ErrUnexpectedEOF
434 }
435 }
436 }
437
438
439 func (fd *FD) WriteToInet4(p []byte, sa *syscall.SockaddrInet4) (int, error) {
440 if err := fd.writeLock(); err != nil {
441 return 0, err
442 }
443 defer fd.writeUnlock()
444 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
445 return 0, err
446 }
447 for {
448 err := unix.SendtoInet4(fd.Sysfd, p, 0, sa)
449 if err == syscall.EINTR {
450 continue
451 }
452 if err == syscall.EAGAIN && fd.pd.pollable() {
453 if err = fd.pd.waitWrite(fd.isFile); err == nil {
454 continue
455 }
456 }
457 if err != nil {
458 return 0, err
459 }
460 return len(p), nil
461 }
462 }
463
464
465 func (fd *FD) WriteToInet6(p []byte, sa *syscall.SockaddrInet6) (int, error) {
466 if err := fd.writeLock(); err != nil {
467 return 0, err
468 }
469 defer fd.writeUnlock()
470 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
471 return 0, err
472 }
473 for {
474 err := unix.SendtoInet6(fd.Sysfd, p, 0, sa)
475 if err == syscall.EINTR {
476 continue
477 }
478 if err == syscall.EAGAIN && fd.pd.pollable() {
479 if err = fd.pd.waitWrite(fd.isFile); err == nil {
480 continue
481 }
482 }
483 if err != nil {
484 return 0, err
485 }
486 return len(p), nil
487 }
488 }
489
490
491 func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) {
492 if err := fd.writeLock(); err != nil {
493 return 0, err
494 }
495 defer fd.writeUnlock()
496 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
497 return 0, err
498 }
499 for {
500 err := syscall.Sendto(fd.Sysfd, p, 0, sa)
501 if err == syscall.EINTR {
502 continue
503 }
504 if err == syscall.EAGAIN && fd.pd.pollable() {
505 if err = fd.pd.waitWrite(fd.isFile); err == nil {
506 continue
507 }
508 }
509 if err != nil {
510 return 0, err
511 }
512 return len(p), nil
513 }
514 }
515
516
517 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
518 if err := fd.writeLock(); err != nil {
519 return 0, 0, err
520 }
521 defer fd.writeUnlock()
522 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
523 return 0, 0, err
524 }
525 for {
526 n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0)
527 if err == syscall.EINTR {
528 continue
529 }
530 if err == syscall.EAGAIN && fd.pd.pollable() {
531 if err = fd.pd.waitWrite(fd.isFile); err == nil {
532 continue
533 }
534 }
535 if err != nil {
536 return n, 0, err
537 }
538 return n, len(oob), err
539 }
540 }
541
542
543 func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (int, int, error) {
544 if err := fd.writeLock(); err != nil {
545 return 0, 0, err
546 }
547 defer fd.writeUnlock()
548 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
549 return 0, 0, err
550 }
551 for {
552 n, err := unix.SendmsgNInet4(fd.Sysfd, p, oob, sa, 0)
553 if err == syscall.EINTR {
554 continue
555 }
556 if err == syscall.EAGAIN && fd.pd.pollable() {
557 if err = fd.pd.waitWrite(fd.isFile); err == nil {
558 continue
559 }
560 }
561 if err != nil {
562 return n, 0, err
563 }
564 return n, len(oob), err
565 }
566 }
567
568
569 func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (int, int, error) {
570 if err := fd.writeLock(); err != nil {
571 return 0, 0, err
572 }
573 defer fd.writeUnlock()
574 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
575 return 0, 0, err
576 }
577 for {
578 n, err := unix.SendmsgNInet6(fd.Sysfd, p, oob, sa, 0)
579 if err == syscall.EINTR {
580 continue
581 }
582 if err == syscall.EAGAIN && fd.pd.pollable() {
583 if err = fd.pd.waitWrite(fd.isFile); err == nil {
584 continue
585 }
586 }
587 if err != nil {
588 return n, 0, err
589 }
590 return n, len(oob), err
591 }
592 }
593
594
595 func (fd *FD) Accept() (int, syscall.Sockaddr, string, error) {
596 if err := fd.readLock(); err != nil {
597 return -1, nil, "", err
598 }
599 defer fd.readUnlock()
600
601 if err := fd.pd.prepareRead(fd.isFile); err != nil {
602 return -1, nil, "", err
603 }
604 for {
605 s, rsa, errcall, err := accept(fd.Sysfd)
606 if err == nil {
607 return s, rsa, "", err
608 }
609 switch err {
610 case syscall.EINTR:
611 continue
612 case syscall.EAGAIN:
613 if fd.pd.pollable() {
614 if err = fd.pd.waitRead(fd.isFile); err == nil {
615 continue
616 }
617 }
618 case syscall.ECONNABORTED:
619
620
621
622 continue
623 }
624 return -1, nil, errcall, err
625 }
626 }
627
628
629 func (fd *FD) Seek(offset int64, whence int) (int64, error) {
630 if err := fd.incref(); err != nil {
631 return 0, err
632 }
633 defer fd.decref()
634 return syscall.Seek(fd.Sysfd, offset, whence)
635 }
636
637
638
639
640 func (fd *FD) ReadDirent(buf []byte) (int, error) {
641 if err := fd.incref(); err != nil {
642 return 0, err
643 }
644 defer fd.decref()
645 for {
646 n, err := ignoringEINTRIO(syscall.ReadDirent, fd.Sysfd, buf)
647 if err != nil {
648 n = 0
649 if err == syscall.EAGAIN && fd.pd.pollable() {
650 if err = fd.pd.waitRead(fd.isFile); err == nil {
651 continue
652 }
653 }
654 }
655
656 return n, err
657 }
658 }
659
660
661 func (fd *FD) Fchmod(mode uint32) error {
662 if err := fd.incref(); err != nil {
663 return err
664 }
665 defer fd.decref()
666 return ignoringEINTR(func() error {
667 return syscall.Fchmod(fd.Sysfd, mode)
668 })
669 }
670
671
672 func (fd *FD) Fchdir() error {
673 if err := fd.incref(); err != nil {
674 return err
675 }
676 defer fd.decref()
677 return syscall.Fchdir(fd.Sysfd)
678 }
679
680
681 func (fd *FD) Fstat(s *syscall.Stat_t) error {
682 if err := fd.incref(); err != nil {
683 return err
684 }
685 defer fd.decref()
686 return ignoringEINTR(func() error {
687 return syscall.Fstat(fd.Sysfd, s)
688 })
689 }
690
691
692
693 var tryDupCloexec = int32(1)
694
695
696 func DupCloseOnExec(fd int) (int, string, error) {
697 if syscall.F_DUPFD_CLOEXEC != 0 && atomic.LoadInt32(&tryDupCloexec) == 1 {
698 r0, e1 := fcntl(fd, syscall.F_DUPFD_CLOEXEC, 0)
699 if e1 == nil {
700 return r0, "", nil
701 }
702 switch e1.(syscall.Errno) {
703 case syscall.EINVAL, syscall.ENOSYS:
704
705
706
707 atomic.StoreInt32(&tryDupCloexec, 0)
708 default:
709 return -1, "fcntl", e1
710 }
711 }
712 return dupCloseOnExecOld(fd)
713 }
714
715
716
717 func dupCloseOnExecOld(fd int) (int, string, error) {
718 syscall.ForkLock.RLock()
719 defer syscall.ForkLock.RUnlock()
720 newfd, err := syscall.Dup(fd)
721 if err != nil {
722 return -1, "dup", err
723 }
724 syscall.CloseOnExec(newfd)
725 return newfd, "", nil
726 }
727
728
729 func (fd *FD) Dup() (int, string, error) {
730 if err := fd.incref(); err != nil {
731 return -1, "", err
732 }
733 defer fd.decref()
734 return DupCloseOnExec(fd.Sysfd)
735 }
736
737
738
739
740 func (fd *FD) WaitWrite() error {
741 return fd.pd.waitWrite(fd.isFile)
742 }
743
744
745 func (fd *FD) WriteOnce(p []byte) (int, error) {
746 if err := fd.writeLock(); err != nil {
747 return 0, err
748 }
749 defer fd.writeUnlock()
750 return ignoringEINTRIO(syscall.Write, fd.Sysfd, p)
751 }
752
753
754 func (fd *FD) RawRead(f func(uintptr) bool) error {
755 if err := fd.readLock(); err != nil {
756 return err
757 }
758 defer fd.readUnlock()
759 if err := fd.pd.prepareRead(fd.isFile); err != nil {
760 return err
761 }
762 for {
763 if f(uintptr(fd.Sysfd)) {
764 return nil
765 }
766 if err := fd.pd.waitRead(fd.isFile); err != nil {
767 return err
768 }
769 }
770 }
771
772
773 func (fd *FD) RawWrite(f func(uintptr) bool) error {
774 if err := fd.writeLock(); err != nil {
775 return err
776 }
777 defer fd.writeUnlock()
778 if err := fd.pd.prepareWrite(fd.isFile); err != nil {
779 return err
780 }
781 for {
782 if f(uintptr(fd.Sysfd)) {
783 return nil
784 }
785 if err := fd.pd.waitWrite(fd.isFile); err != nil {
786 return err
787 }
788 }
789 }
790
791
792 func ignoringEINTRIO(fn func(fd int, p []byte) (int, error), fd int, p []byte) (int, error) {
793 for {
794 n, err := fn(fd, p)
795 if err != syscall.EINTR {
796 return n, err
797 }
798 }
799 }
800
View as plain text