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