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
)