Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(17)

Side by Side Diff: src/pkg/net/ipsock_plan9.go

Issue 6820124: code review 6820124: net: consolidate common socket functions for Plan 9 (Closed)
Patch Set: diff -r 27bce3a1244d https://code.google.com/p/go Created 12 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pkg/net/fd_plan9.go ('k') | src/pkg/net/net.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // IP sockets stubs for Plan 9 5 // IP sockets stubs for Plan 9
6 6
7 package net 7 package net
8 8
9 import ( 9 import (
10 "errors" 10 "errors"
11 "io"
12 "os" 11 "os"
13 "syscall"
14 "time"
15 ) 12 )
16 13
17 // /sys/include/ape/sys/socket.h:/SOMAXCONN 14 // /sys/include/ape/sys/socket.h:/SOMAXCONN
18 var listenerBacklog = 5 15 var listenerBacklog = 5
19 16
20 // probeIPv6Stack returns two boolean values. If the first boolean 17 // probeIPv6Stack returns two boolean values. If the first boolean
21 // value is true, kernel supports basic IPv6 functionality. If the 18 // value is true, kernel supports basic IPv6 functionality. If the
22 // second boolean value is true, kernel supports IPv6 IPv4-mapping. 19 // second boolean value is true, kernel supports IPv6 IPv4-mapping.
23 func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) { 20 func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) {
24 return false, false 21 return false, false
25 } 22 }
26 23
27 var canCancelIO = true // used for testing current package
28
29 func sysInit() {
30 }
31
32 // parsePlan9Addr parses address of the form [ip!]port (e.g. 127.0.0.1!80). 24 // parsePlan9Addr parses address of the form [ip!]port (e.g. 127.0.0.1!80).
33 func parsePlan9Addr(s string) (ip IP, iport int, err error) { 25 func parsePlan9Addr(s string) (ip IP, iport int, err error) {
34 addr := IPv4zero // address contains port only 26 addr := IPv4zero // address contains port only
35 i := byteIndex(s, '!') 27 i := byteIndex(s, '!')
36 if i >= 0 { 28 if i >= 0 {
37 addr = ParseIP(s[:i]) 29 addr = ParseIP(s[:i])
38 if addr == nil { 30 if addr == nil {
39 return nil, 0, errors.New("net: parsing IP failed") 31 return nil, 0, errors.New("net: parsing IP failed")
40 } 32 }
41 } 33 }
(...skipping 27 matching lines...) Expand all
69 case "tcp": 61 case "tcp":
70 addr = &TCPAddr{ip, port} 62 addr = &TCPAddr{ip, port}
71 case "udp": 63 case "udp":
72 addr = &UDPAddr{ip, port} 64 addr = &UDPAddr{ip, port}
73 default: 65 default:
74 return nil, errors.New("unknown protocol " + proto) 66 return nil, errors.New("unknown protocol " + proto)
75 } 67 }
76 return addr, nil 68 return addr, nil
77 } 69 }
78 70
79 type plan9Conn struct {
80 proto, name, dir string
81 ctl, data *os.File
82 laddr, raddr Addr
83 }
84
85 func newPlan9Conn(proto, name string, ctl *os.File, laddr, raddr Addr) *plan9Con n {
86 return &plan9Conn{proto, name, "/net/" + proto + "/" + name, ctl, nil, l addr, raddr}
87 }
88
89 func (c *plan9Conn) ok() bool { return c != nil && c.ctl != nil }
90
91 // Implementation of the Conn interface - see Conn for documentation.
92
93 // Read implements the Conn Read method.
94 func (c *plan9Conn) Read(b []byte) (n int, err error) {
95 if !c.ok() {
96 return 0, syscall.EINVAL
97 }
98 if c.data == nil {
99 c.data, err = os.OpenFile(c.dir+"/data", os.O_RDWR, 0)
100 if err != nil {
101 return 0, err
102 }
103 }
104 n, err = c.data.Read(b)
105 if c.proto == "udp" && err == io.EOF {
106 n = 0
107 err = nil
108 }
109 return
110 }
111
112 // Write implements the Conn Write method.
113 func (c *plan9Conn) Write(b []byte) (n int, err error) {
114 if !c.ok() {
115 return 0, syscall.EINVAL
116 }
117 if c.data == nil {
118 c.data, err = os.OpenFile(c.dir+"/data", os.O_RDWR, 0)
119 if err != nil {
120 return 0, err
121 }
122 }
123 return c.data.Write(b)
124 }
125
126 // Close closes the connection.
127 func (c *plan9Conn) Close() error {
128 if !c.ok() {
129 return syscall.EINVAL
130 }
131 err := c.ctl.Close()
132 if err != nil {
133 return err
134 }
135 if c.data != nil {
136 err = c.data.Close()
137 }
138 c.ctl = nil
139 c.data = nil
140 return err
141 }
142
143 // LocalAddr returns the local network address.
144 func (c *plan9Conn) LocalAddr() Addr {
145 if !c.ok() {
146 return nil
147 }
148 return c.laddr
149 }
150
151 // RemoteAddr returns the remote network address.
152 func (c *plan9Conn) RemoteAddr() Addr {
153 if !c.ok() {
154 return nil
155 }
156 return c.raddr
157 }
158
159 // SetDeadline implements the Conn SetDeadline method.
160 func (c *plan9Conn) SetDeadline(t time.Time) error {
161 return syscall.EPLAN9
162 }
163
164 // SetReadDeadline implements the Conn SetReadDeadline method.
165 func (c *plan9Conn) SetReadDeadline(t time.Time) error {
166 return syscall.EPLAN9
167 }
168
169 // SetWriteDeadline implements the Conn SetWriteDeadline method.
170 func (c *plan9Conn) SetWriteDeadline(t time.Time) error {
171 return syscall.EPLAN9
172 }
173
174 // SetReadBuffer sets the size of the operating system's receive
175 // buffer associated with the connection.
176 func (c *plan9Conn) SetReadBuffer(bytes int) error {
177 return syscall.EPLAN9
178 }
179
180 // SetWriteBuffer sets the size of the operating system's transmit
181 // buffer associated with the connection.
182 func (c *plan9Conn) SetWriteBuffer(bytes int) error {
183 return syscall.EPLAN9
184 }
185
186 // File returns a copy of the underlying os.File, set to blocking
187 // mode. It is the caller's responsibility to close f when finished.
188 // Closing c does not affect f, and closing f does not affect c.
189 func (c *plan9Conn) File() (f *os.File, err error) {
190 return nil, syscall.EPLAN9
191 }
192
193 func startPlan9(net string, addr Addr) (ctl *os.File, dest, proto, name string, err error) { 71 func startPlan9(net string, addr Addr) (ctl *os.File, dest, proto, name string, err error) {
194 var ( 72 var (
195 ip IP 73 ip IP
196 port int 74 port int
197 ) 75 )
198 switch a := addr.(type) { 76 switch a := addr.(type) {
199 case *TCPAddr: 77 case *TCPAddr:
200 proto = "tcp" 78 proto = "tcp"
201 ip = a.IP 79 ip = a.IP
202 port = a.Port 80 port = a.Port
(...skipping 16 matching lines...) Expand all
219 } 97 }
220 var buf [16]byte 98 var buf [16]byte
221 n, err := f.Read(buf[:]) 99 n, err := f.Read(buf[:])
222 if err != nil { 100 if err != nil {
223 f.Close() 101 f.Close()
224 return 102 return
225 } 103 }
226 return f, dest, proto, string(buf[:n]), nil 104 return f, dest, proto, string(buf[:n]), nil
227 } 105 }
228 106
229 func dialPlan9(net string, laddr, raddr Addr) (c *plan9Conn, err error) { 107 func dialPlan9(net string, laddr, raddr Addr) (*netFD, error) {
230 f, dest, proto, name, err := startPlan9(net, raddr) 108 f, dest, proto, name, err := startPlan9(net, raddr)
231 if err != nil { 109 if err != nil {
232 » » return 110 » » return nil, err
233 } 111 }
234 _, err = f.WriteString("connect " + dest) 112 _, err = f.WriteString("connect " + dest)
235 if err != nil { 113 if err != nil {
236 f.Close() 114 f.Close()
237 » » return 115 » » return nil, err
238 } 116 }
239 laddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/local") 117 laddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/local")
240 if err != nil { 118 if err != nil {
241 f.Close() 119 f.Close()
242 » » return 120 » » return nil, err
243 } 121 }
244 raddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/remote") 122 raddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/remote")
245 if err != nil { 123 if err != nil {
246 f.Close() 124 f.Close()
247 » » return 125 » » return nil, err
248 } 126 }
249 » return newPlan9Conn(proto, name, f, laddr, raddr), nil 127 » return newFD(proto, name, f, laddr, raddr), nil
250 } 128 }
251 129
252 type plan9Listener struct { 130 func listenPlan9(net string, laddr Addr) (*netFD, error) {
253 » proto, name, dir string
254 » ctl *os.File
255 » laddr Addr
256 }
257
258 func listenPlan9(net string, laddr Addr) (l *plan9Listener, err error) {
259 f, dest, proto, name, err := startPlan9(net, laddr) 131 f, dest, proto, name, err := startPlan9(net, laddr)
260 if err != nil { 132 if err != nil {
261 » » return 133 » » return nil, err
262 } 134 }
263 _, err = f.WriteString("announce " + dest) 135 _, err = f.WriteString("announce " + dest)
264 if err != nil { 136 if err != nil {
265 f.Close() 137 f.Close()
266 » » return 138 » » return nil, err
267 } 139 }
268 laddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/local") 140 laddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/local")
269 if err != nil { 141 if err != nil {
270 f.Close() 142 f.Close()
271 » » return 143 » » return nil, err
272 } 144 }
273 » l = new(plan9Listener) 145 » return &netFD{proto: proto, name: name, dir: "/net/" + proto + "/" + nam e, ctl: f, laddr: laddr}, nil
274 » l.proto = proto
275 » l.name = name
276 » l.dir = "/net/" + proto + "/" + name
277 » l.ctl = f
278 » l.laddr = laddr
279 » return l, nil
280 } 146 }
281 147
282 func (l *plan9Listener) plan9Conn() *plan9Conn { 148 func (l *netFD) netFD() *netFD {
283 » return newPlan9Conn(l.proto, l.name, l.ctl, l.laddr, nil) 149 » return newFD(l.proto, l.name, l.ctl, l.laddr, nil)
284 } 150 }
285 151
286 func (l *plan9Listener) acceptPlan9() (c *plan9Conn, err error) { 152 func (l *netFD) acceptPlan9() (*netFD, error) {
287 f, err := os.Open(l.dir + "/listen") 153 f, err := os.Open(l.dir + "/listen")
288 if err != nil { 154 if err != nil {
289 » » return 155 » » return nil, err
290 } 156 }
291 var buf [16]byte 157 var buf [16]byte
292 n, err := f.Read(buf[:]) 158 n, err := f.Read(buf[:])
293 if err != nil { 159 if err != nil {
294 f.Close() 160 f.Close()
295 » » return 161 » » return nil, err
296 } 162 }
297 name := string(buf[:n]) 163 name := string(buf[:n])
298 laddr, err := readPlan9Addr(l.proto, l.dir+"/local") 164 laddr, err := readPlan9Addr(l.proto, l.dir+"/local")
299 if err != nil { 165 if err != nil {
300 f.Close() 166 f.Close()
301 » » return 167 » » return nil, err
302 } 168 }
303 raddr, err := readPlan9Addr(l.proto, l.dir+"/remote") 169 raddr, err := readPlan9Addr(l.proto, l.dir+"/remote")
304 if err != nil { 170 if err != nil {
305 f.Close() 171 f.Close()
306 » » return 172 » » return nil, err
307 } 173 }
308 » return newPlan9Conn(l.proto, name, f, laddr, raddr), nil 174 » return newFD(l.proto, name, f, laddr, raddr), nil
309 } 175 }
310
311 func (l *plan9Listener) Accept() (c Conn, err error) {
312 c1, err := l.acceptPlan9()
313 if err != nil {
314 return
315 }
316 return c1, nil
317 }
318
319 func (l *plan9Listener) Close() error {
320 if l == nil || l.ctl == nil {
321 return syscall.EINVAL
322 }
323 return l.ctl.Close()
324 }
325
326 func (l *plan9Listener) Addr() Addr { return l.laddr }
327
328 // SetDeadline sets the deadline associated with the listener.
329 // A zero time value disables the deadline.
330 func (l *plan9Listener) SetDeadline(t time.Time) error {
331 return syscall.EPLAN9
332 }
333
334 // File returns a copy of the underlying os.File, set to blocking
335 // mode. It is the caller's responsibility to close f when finished.
336 // Closing l does not affect f, and closing f does not affect l.
337 func (l *plan9Listener) File() (f *os.File, err error) {
338 return nil, syscall.EPLAN9
339 }
OLDNEW
« no previous file with comments | « src/pkg/net/fd_plan9.go ('k') | src/pkg/net/net.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b