1 // Copyright 2011 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.
14 func (fd
*netFD
) status(ln
int) (string, error
) {
16 return "", syscall
.EINVAL
19 status
, err
:= os
.Open(fd
.dir
+ "/status")
24 buf
:= make([]byte, ln
)
25 n
, err
:= io
.ReadFull(status
, buf
[:])
29 return string(buf
[:n
]), nil
32 func newFileFD(f
*os
.File
) (net
*netFD
, err error
) {
34 close := func(fd
int) {
40 path
, err
:= syscall
.Fd2path(int(f
.Fd()))
42 return nil, os
.NewSyscallError("fd2path", err
)
44 comp
:= splitAtBytes(path
, "/")
46 if n
< 3 || comp
[0][0:3] != "net" {
47 return nil, syscall
.EPLAN9
51 switch file
:= comp
[n
-1]; file
{
53 fd
, err
:= syscall
.Dup(int(f
.Fd()), -1)
55 return nil, os
.NewSyscallError("dup", err
)
59 dir
:= netdir
+ "/" + comp
[n
-2]
60 ctl
= os
.NewFile(uintptr(fd
), dir
+"/"+file
)
61 ctl
.Seek(0, io
.SeekStart
)
63 n
, err
:= ctl
.Read(buf
[:])
67 name
= string(buf
[:n
])
70 return nil, errors
.New("could not find control file for connection")
72 dir
:= netdir
+ "/" + comp
[1] + "/" + name
73 ctl
, err
= os
.OpenFile(dir
+"/ctl", os
.O_RDWR
, 0)
77 defer close(int(ctl
.Fd()))
79 dir
:= netdir
+ "/" + comp
[1] + "/" + name
80 laddr
, err
:= readPlan9Addr(comp
[1], dir
+"/local")
84 return newFD(comp
[1], name
, nil, ctl
, nil, laddr
, nil)
87 func fileConn(f
*os
.File
) (Conn
, error
) {
88 fd
, err
:= newFileFD(f
)
93 return nil, syscall
.EINVAL
96 fd
.data
, err
= os
.OpenFile(fd
.dir
+"/data", os
.O_RDWR
, 0)
101 switch fd
.laddr
.(type) {
103 return newTCPConn(fd
), nil
105 return newUDPConn(fd
), nil
107 return nil, syscall
.EPLAN9
110 func fileListener(f
*os
.File
) (Listener
, error
) {
111 fd
, err
:= newFileFD(f
)
115 switch fd
.laddr
.(type) {
118 return nil, syscall
.EPLAN9
121 // check that file corresponds to a listener
122 s
, err
:= fd
.status(len("Listen"))
127 return nil, errors
.New("file does not represent a listener")
130 return &TCPListener
{fd
}, nil
133 func filePacketConn(f
*os
.File
) (PacketConn
, error
) {
134 return nil, syscall
.EPLAN9