Source file
src/net/fd_plan9.go
1
2
3
4
5 package net
6
7 import (
8 "internal/poll"
9 "io"
10 "os"
11 "syscall"
12 "time"
13 )
14
15
16 type netFD struct {
17 pfd poll.FD
18
19
20 net string
21 n string
22 dir string
23 listen, ctl, data *os.File
24 laddr, raddr Addr
25 isStream bool
26 }
27
28 var netdir = "/net"
29
30 func newFD(net, name string, listen, ctl, data *os.File, laddr, raddr Addr) *netFD {
31 ret := &netFD{
32 net: net,
33 n: name,
34 dir: netdir + "/" + net + "/" + name,
35 listen: listen,
36 ctl: ctl, data: data,
37 laddr: laddr,
38 raddr: raddr,
39 }
40 ret.pfd.Destroy = ret.destroy
41 return ret
42 }
43
44 func (fd *netFD) init() error {
45
46 return nil
47 }
48
49 func (fd *netFD) name() string {
50 var ls, rs string
51 if fd.laddr != nil {
52 ls = fd.laddr.String()
53 }
54 if fd.raddr != nil {
55 rs = fd.raddr.String()
56 }
57 return fd.net + ":" + ls + "->" + rs
58 }
59
60 func (fd *netFD) ok() bool { return fd != nil && fd.ctl != nil }
61
62 func (fd *netFD) destroy() {
63 if !fd.ok() {
64 return
65 }
66 err := fd.ctl.Close()
67 if fd.data != nil {
68 if err1 := fd.data.Close(); err1 != nil && err == nil {
69 err = err1
70 }
71 }
72 if fd.listen != nil {
73 if err1 := fd.listen.Close(); err1 != nil && err == nil {
74 err = err1
75 }
76 }
77 fd.ctl = nil
78 fd.data = nil
79 fd.listen = nil
80 }
81
82 func (fd *netFD) Read(b []byte) (n int, err error) {
83 if fd == nil {
84 return 0, syscall.EINVAL
85 }
86 if fd.data == nil {
87 return 0, ErrClosed
88 }
89 n, err = fd.pfd.Read(fd.data.Read, b)
90 if err == io.EOF {
91 if fd.data == nil {
92 err = ErrClosed
93 } else if fd.net == "udp" {
94 n = 0
95 err = nil
96 }
97 }
98 return
99 }
100
101 func (fd *netFD) Write(b []byte) (n int, err error) {
102 if !fd.ok() || fd.data == nil {
103 return 0, syscall.EINVAL
104 }
105 return fd.pfd.Write(fd.data.Write, b)
106 }
107
108 func (fd *netFD) closeRead() error {
109 if !fd.ok() {
110 return syscall.EINVAL
111 }
112 return syscall.EPLAN9
113 }
114
115 func (fd *netFD) closeWrite() error {
116 if !fd.ok() {
117 return syscall.EINVAL
118 }
119 return syscall.EPLAN9
120 }
121
122 func (fd *netFD) Close() error {
123 if err := fd.pfd.Close(); err != nil {
124 return err
125 }
126 if !fd.ok() {
127 return syscall.EINVAL
128 }
129 if fd.net == "tcp" {
130
131 _, err := fd.ctl.WriteString("close")
132 if err != nil {
133 return err
134 }
135 }
136 if fd.net == "udp" {
137
138
139 fd.SetReadDeadline(time.Now().Add(-time.Hour))
140 }
141 err := fd.ctl.Close()
142 if fd.data != nil {
143 if err1 := fd.data.Close(); err1 != nil && err == nil {
144 err = err1
145 }
146 }
147 if fd.listen != nil {
148 if err1 := fd.listen.Close(); err1 != nil && err == nil {
149 err = err1
150 }
151 }
152 fd.ctl = nil
153 fd.data = nil
154 fd.listen = nil
155 return err
156 }
157
158
159 func (fd *netFD) dup() (*os.File, error) {
160 if !fd.ok() || fd.data == nil {
161 return nil, syscall.EINVAL
162 }
163 return fd.file(fd.data, fd.dir+"/data")
164 }
165
166 func (l *TCPListener) dup() (*os.File, error) {
167 if !l.fd.ok() {
168 return nil, syscall.EINVAL
169 }
170 return l.fd.file(l.fd.ctl, l.fd.dir+"/ctl")
171 }
172
173 func (fd *netFD) file(f *os.File, s string) (*os.File, error) {
174 dfd, err := syscall.Dup(int(f.Fd()), -1)
175 if err != nil {
176 return nil, os.NewSyscallError("dup", err)
177 }
178 return os.NewFile(uintptr(dfd), s), nil
179 }
180
181 func setReadBuffer(fd *netFD, bytes int) error {
182 return syscall.EPLAN9
183 }
184
185 func setWriteBuffer(fd *netFD, bytes int) error {
186 return syscall.EPLAN9
187 }
188
189 func (fd *netFD) SetDeadline(t time.Time) error {
190 return fd.pfd.SetDeadline(t)
191 }
192
193 func (fd *netFD) SetReadDeadline(t time.Time) error {
194 return fd.pfd.SetReadDeadline(t)
195 }
196
197 func (fd *netFD) SetWriteDeadline(t time.Time) error {
198 return fd.pfd.SetWriteDeadline(t)
199 }
200
View as plain text