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