...
1
2
3
18
19 package fifo
20
21 import (
22 "syscall"
23 )
24
25
26
27 func (f *fifo) SyscallConn() (syscall.RawConn, error) {
28
29 select {
30 case <-f.closed:
31 return nil, ErrClosed
32 default:
33 }
34
35 select {
36 case <-f.closed:
37 return nil, ErrClosed
38 case <-f.opened:
39 return f.file.SyscallConn()
40 default:
41 }
42
43
44
45 rc := &rawConn{f: f, ready: make(chan struct{})}
46 go func() {
47 select {
48 case <-f.closed:
49 return
50 case <-f.opened:
51 rc.raw, rc.err = f.file.SyscallConn()
52 close(rc.ready)
53 }
54 }()
55
56 return rc, nil
57 }
58
59 type rawConn struct {
60 f *fifo
61 ready chan struct{}
62 raw syscall.RawConn
63 err error
64 }
65
66 func (r *rawConn) Control(f func(fd uintptr)) error {
67 select {
68 case <-r.f.closed:
69 return ErrCtrlClosed
70 case <-r.ready:
71 }
72
73 if r.err != nil {
74 return r.err
75 }
76
77 return r.raw.Control(f)
78 }
79
80 func (r *rawConn) Read(f func(fd uintptr) (done bool)) error {
81 if r.f.flag&syscall.O_WRONLY > 0 {
82 return ErrRdFrmWRONLY
83 }
84
85 select {
86 case <-r.f.closed:
87 return ErrReadClosed
88 case <-r.ready:
89 }
90
91 if r.err != nil {
92 return r.err
93 }
94
95 return r.raw.Read(f)
96 }
97
98 func (r *rawConn) Write(f func(fd uintptr) (done bool)) error {
99 if r.f.flag&(syscall.O_WRONLY|syscall.O_RDWR) == 0 {
100 return ErrWrToRDONLY
101 }
102
103 select {
104 case <-r.f.closed:
105 return ErrWriteClosed
106 case <-r.ready:
107 }
108
109 if r.err != nil {
110 return r.err
111 }
112
113 return r.raw.Write(f)
114 }
115
View as plain text