OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [net/] [ipsock_plan9.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2009 The Go Authors.  All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
// IP sockets stubs for Plan 9
6
 
7
package net
8
 
9
import (
10
        "errors"
11
        "io"
12
        "os"
13
        "time"
14
)
15
 
16
// probeIPv6Stack returns two boolean values.  If the first boolean value is
17
// true, kernel supports basic IPv6 functionality.  If the second
18
// boolean value is true, kernel supports IPv6 IPv4-mapping.
19
func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) {
20
        return false, false
21
}
22
 
23
// parsePlan9Addr parses address of the form [ip!]port (e.g. 127.0.0.1!80).
24
func parsePlan9Addr(s string) (ip IP, iport int, err error) {
25
        addr := IPv4zero // address contains port only
26
        i := byteIndex(s, '!')
27
        if i >= 0 {
28
                addr = ParseIP(s[:i])
29
                if addr == nil {
30
                        return nil, 0, errors.New("net: parsing IP failed")
31
                }
32
        }
33
        p, _, ok := dtoi(s[i+1:], 0)
34
        if !ok {
35
                return nil, 0, errors.New("net: parsing port failed")
36
        }
37
        if p < 0 || p > 0xFFFF {
38
                return nil, 0, &AddrError{"invalid port", string(p)}
39
        }
40
        return addr, p, nil
41
}
42
 
43
func readPlan9Addr(proto, filename string) (addr Addr, err error) {
44
        var buf [128]byte
45
 
46
        f, err := os.Open(filename)
47
        if err != nil {
48
                return
49
        }
50
        n, err := f.Read(buf[:])
51
        if err != nil {
52
                return
53
        }
54
        ip, port, err := parsePlan9Addr(string(buf[:n]))
55
        if err != nil {
56
                return
57
        }
58
        switch proto {
59
        case "tcp":
60
                addr = &TCPAddr{ip, port}
61
        case "udp":
62
                addr = &UDPAddr{ip, port}
63
        default:
64
                return nil, errors.New("unknown protocol " + proto)
65
        }
66
        return addr, nil
67
}
68
 
69
type plan9Conn struct {
70
        proto, name, dir string
71
        ctl, data        *os.File
72
        laddr, raddr     Addr
73
}
74
 
75
func newPlan9Conn(proto, name string, ctl *os.File, laddr, raddr Addr) *plan9Conn {
76
        return &plan9Conn{proto, name, "/net/" + proto + "/" + name, ctl, nil, laddr, raddr}
77
}
78
 
79
func (c *plan9Conn) ok() bool { return c != nil && c.ctl != nil }
80
 
81
// Implementation of the Conn interface - see Conn for documentation.
82
 
83
// Read implements the Conn Read method.
84
func (c *plan9Conn) Read(b []byte) (n int, err error) {
85
        if !c.ok() {
86
                return 0, os.EINVAL
87
        }
88
        if c.data == nil {
89
                c.data, err = os.OpenFile(c.dir+"/data", os.O_RDWR, 0)
90
                if err != nil {
91
                        return 0, err
92
                }
93
        }
94
        n, err = c.data.Read(b)
95
        if c.proto == "udp" && err == io.EOF {
96
                n = 0
97
                err = nil
98
        }
99
        return
100
}
101
 
102
// Write implements the Conn Write method.
103
func (c *plan9Conn) Write(b []byte) (n int, err error) {
104
        if !c.ok() {
105
                return 0, os.EINVAL
106
        }
107
        if c.data == nil {
108
                c.data, err = os.OpenFile(c.dir+"/data", os.O_RDWR, 0)
109
                if err != nil {
110
                        return 0, err
111
                }
112
        }
113
        return c.data.Write(b)
114
}
115
 
116
// Close closes the connection.
117
func (c *plan9Conn) Close() error {
118
        if !c.ok() {
119
                return os.EINVAL
120
        }
121
        err := c.ctl.Close()
122
        if err != nil {
123
                return err
124
        }
125
        if c.data != nil {
126
                err = c.data.Close()
127
        }
128
        c.ctl = nil
129
        c.data = nil
130
        return err
131
}
132
 
133
// LocalAddr returns the local network address.
134
func (c *plan9Conn) LocalAddr() Addr {
135
        if !c.ok() {
136
                return nil
137
        }
138
        return c.laddr
139
}
140
 
141
// RemoteAddr returns the remote network address.
142
func (c *plan9Conn) RemoteAddr() Addr {
143
        if !c.ok() {
144
                return nil
145
        }
146
        return c.raddr
147
}
148
 
149
// SetDeadline implements the Conn SetDeadline method.
150
func (c *plan9Conn) SetDeadline(t time.Time) error {
151
        return os.EPLAN9
152
}
153
 
154
// SetReadDeadline implements the Conn SetReadDeadline method.
155
func (c *plan9Conn) SetReadDeadline(t time.Time) error {
156
        return os.EPLAN9
157
}
158
 
159
// SetWriteDeadline implements the Conn SetWriteDeadline method.
160
func (c *plan9Conn) SetWriteDeadline(t time.Time) error {
161
        return os.EPLAN9
162
}
163
 
164
func startPlan9(net string, addr Addr) (ctl *os.File, dest, proto, name string, err error) {
165
        var (
166
                ip   IP
167
                port int
168
        )
169
        switch a := addr.(type) {
170
        case *TCPAddr:
171
                proto = "tcp"
172
                ip = a.IP
173
                port = a.Port
174
        case *UDPAddr:
175
                proto = "udp"
176
                ip = a.IP
177
                port = a.Port
178
        default:
179
                err = UnknownNetworkError(net)
180
                return
181
        }
182
 
183
        clone, dest, err := queryCS1(proto, ip, port)
184
        if err != nil {
185
                return
186
        }
187
        f, err := os.OpenFile(clone, os.O_RDWR, 0)
188
        if err != nil {
189
                return
190
        }
191
        var buf [16]byte
192
        n, err := f.Read(buf[:])
193
        if err != nil {
194
                return
195
        }
196
        return f, dest, proto, string(buf[:n]), nil
197
}
198
 
199
func dialPlan9(net string, laddr, raddr Addr) (c *plan9Conn, err error) {
200
        f, dest, proto, name, err := startPlan9(net, raddr)
201
        if err != nil {
202
                return
203
        }
204
        _, err = f.WriteString("connect " + dest)
205
        if err != nil {
206
                return
207
        }
208
        laddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/local")
209
        if err != nil {
210
                return
211
        }
212
        raddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/remote")
213
        if err != nil {
214
                return
215
        }
216
        return newPlan9Conn(proto, name, f, laddr, raddr), nil
217
}
218
 
219
type plan9Listener struct {
220
        proto, name, dir string
221
        ctl              *os.File
222
        laddr            Addr
223
}
224
 
225
func listenPlan9(net string, laddr Addr) (l *plan9Listener, err error) {
226
        f, dest, proto, name, err := startPlan9(net, laddr)
227
        if err != nil {
228
                return
229
        }
230
        _, err = f.WriteString("announce " + dest)
231
        if err != nil {
232
                return
233
        }
234
        laddr, err = readPlan9Addr(proto, "/net/"+proto+"/"+name+"/local")
235
        if err != nil {
236
                return
237
        }
238
        l = new(plan9Listener)
239
        l.proto = proto
240
        l.name = name
241
        l.dir = "/net/" + proto + "/" + name
242
        l.ctl = f
243
        l.laddr = laddr
244
        return l, nil
245
}
246
 
247
func (l *plan9Listener) plan9Conn() *plan9Conn {
248
        return newPlan9Conn(l.proto, l.name, l.ctl, l.laddr, nil)
249
}
250
 
251
func (l *plan9Listener) acceptPlan9() (c *plan9Conn, err error) {
252
        f, err := os.Open(l.dir + "/listen")
253
        if err != nil {
254
                return
255
        }
256
        var buf [16]byte
257
        n, err := f.Read(buf[:])
258
        if err != nil {
259
                return
260
        }
261
        name := string(buf[:n])
262
        laddr, err := readPlan9Addr(l.proto, l.dir+"/local")
263
        if err != nil {
264
                return
265
        }
266
        raddr, err := readPlan9Addr(l.proto, l.dir+"/remote")
267
        if err != nil {
268
                return
269
        }
270
        return newPlan9Conn(l.proto, name, f, laddr, raddr), nil
271
}
272
 
273
func (l *plan9Listener) Accept() (c Conn, err error) {
274
        c1, err := l.acceptPlan9()
275
        if err != nil {
276
                return
277
        }
278
        return c1, nil
279
}
280
 
281
func (l *plan9Listener) Close() error {
282
        if l == nil || l.ctl == nil {
283
                return os.EINVAL
284
        }
285
        return l.ctl.Close()
286
}
287
 
288
func (l *plan9Listener) Addr() Addr { return l.laddr }

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.