1 // 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.
15 // Network file descriptor.
19 // immutable until Close
23 listen, ctl, data *os.File
28 var netdir = "/net" // default network
30 func newFD(net, name string, listen, ctl, data *os.File, laddr, raddr Addr) (*netFD, error) {
34 dir: netdir + "/" + net + "/" + name,
40 ret.pfd.Destroy = ret.destroy
44 func (fd *netFD) init() error {
45 // stub for future fd.pd.Init(fd)
49 func (fd *netFD) name() string {
52 ls = fd.laddr.String()
55 rs = fd.raddr.String()
57 return fd.net + ":" + ls + "->" + rs
60 func (fd *netFD) ok() bool { return fd != nil && fd.ctl != nil }
62 func (fd *netFD) destroy() {
68 if err1 := fd.data.Close(); err1 != nil && err == nil {
73 if err1 := fd.listen.Close(); err1 != nil && err == nil {
82 func (fd *netFD) Read(b []byte) (n int, err error) {
83 if !fd.ok() || fd.data == nil {
84 return 0, syscall.EINVAL
86 n, err = fd.pfd.Read(fd.data.Read, b)
87 if fd.net == "udp" && err == io.EOF {
94 func (fd *netFD) Write(b []byte) (n int, err error) {
95 if !fd.ok() || fd.data == nil {
96 return 0, syscall.EINVAL
98 return fd.pfd.Write(fd.data.Write, b)
101 func (fd *netFD) closeRead() error {
103 return syscall.EINVAL
105 return syscall.EPLAN9
108 func (fd *netFD) closeWrite() error {
110 return syscall.EINVAL
112 return syscall.EPLAN9
115 func (fd *netFD) Close() error {
116 if err := fd.pfd.Close(); err != nil {
120 return syscall.EINVAL
123 // The following line is required to unblock Reads.
124 _, err := fd.ctl.WriteString("close")
129 err := fd.ctl.Close()
131 if err1 := fd.data.Close(); err1 != nil && err == nil {
135 if fd.listen != nil {
136 if err1 := fd.listen.Close(); err1 != nil && err == nil {
146 // This method is only called via Conn.
147 func (fd *netFD) dup() (*os.File, error) {
148 if !fd.ok() || fd.data == nil {
149 return nil, syscall.EINVAL
151 return fd.file(fd.data, fd.dir+"/data")
154 func (l *TCPListener) dup() (*os.File, error) {
156 return nil, syscall.EINVAL
158 return l.fd.file(l.fd.ctl, l.fd.dir+"/ctl")
161 func (fd *netFD) file(f *os.File, s string) (*os.File, error) {
162 dfd, err := syscall.Dup(int(f.Fd()), -1)
164 return nil, os.NewSyscallError("dup", err)
166 return os.NewFile(uintptr(dfd), s), nil
169 func setReadBuffer(fd *netFD, bytes int) error {
170 return syscall.EPLAN9
173 func setWriteBuffer(fd *netFD, bytes int) error {
174 return syscall.EPLAN9
177 func (fd *netFD) SetDeadline(t time.Time) error {
178 return fd.pfd.SetDeadline(t)
181 func (fd *netFD) SetReadDeadline(t time.Time) error {
182 return fd.pfd.SetReadDeadline(t)
185 func (fd *netFD) SetWriteDeadline(t time.Time) error {
186 return fd.pfd.SetWriteDeadline(t)