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.
14 // Network file descriptor.
18 // immutable until Close
22 listen
, ctl
, data
*os
.File
27 var netdir
= "/net" // default network
29 func newFD(net
, name
string, listen
, ctl
, data
*os
.File
, laddr
, raddr Addr
) (*netFD
, error
) {
33 dir
: netdir
+ "/" + net
+ "/" + name
,
39 ret
.pfd
.Destroy
= ret
.destroy
43 func (fd
*netFD
) init() error
{
44 // stub for future fd.pd.Init(fd)
48 func (fd
*netFD
) name() string {
51 ls
= fd
.laddr
.String()
54 rs
= fd
.raddr
.String()
56 return fd
.net
+ ":" + ls
+ "->" + rs
59 func (fd
*netFD
) ok() bool { return fd
!= nil && fd
.ctl
!= nil }
61 func (fd
*netFD
) destroy() {
67 if err1
:= fd
.data
.Close(); err1
!= nil && err
== nil {
72 if err1
:= fd
.listen
.Close(); err1
!= nil && err
== nil {
81 func (fd
*netFD
) Read(b
[]byte) (n
int, err error
) {
82 if !fd
.ok() || fd
.data
== nil {
83 return 0, syscall
.EINVAL
85 n
, err
= fd
.pfd
.Read(fd
.data
.Read
, b
)
86 if fd
.net
== "udp" && err
== io
.EOF
{
93 func (fd
*netFD
) Write(b
[]byte) (n
int, err error
) {
94 if !fd
.ok() || fd
.data
== nil {
95 return 0, syscall
.EINVAL
97 return fd
.pfd
.Write(fd
.data
.Write
, b
)
100 func (fd
*netFD
) closeRead() error
{
102 return syscall
.EINVAL
104 return syscall
.EPLAN9
107 func (fd
*netFD
) closeWrite() error
{
109 return syscall
.EINVAL
111 return syscall
.EPLAN9
114 func (fd
*netFD
) Close() error
{
115 if err
:= fd
.pfd
.Close(); err
!= nil {
119 return syscall
.EINVAL
122 // The following line is required to unblock Reads.
123 _
, err
:= fd
.ctl
.WriteString("close")
128 err
:= fd
.ctl
.Close()
130 if err1
:= fd
.data
.Close(); err1
!= nil && err
== nil {
134 if fd
.listen
!= nil {
135 if err1
:= fd
.listen
.Close(); err1
!= nil && err
== nil {
145 // This method is only called via Conn.
146 func (fd
*netFD
) dup() (*os
.File
, error
) {
147 if !fd
.ok() || fd
.data
== nil {
148 return nil, syscall
.EINVAL
150 return fd
.file(fd
.data
, fd
.dir
+"/data")
153 func (l
*TCPListener
) dup() (*os
.File
, error
) {
155 return nil, syscall
.EINVAL
157 return l
.fd
.file(l
.fd
.ctl
, l
.fd
.dir
+"/ctl")
160 func (fd
*netFD
) file(f
*os
.File
, s
string) (*os
.File
, error
) {
161 dfd
, err
:= syscall
.Dup(int(f
.Fd()), -1)
163 return nil, os
.NewSyscallError("dup", err
)
165 return os
.NewFile(uintptr(dfd
), s
), nil
168 func setReadBuffer(fd
*netFD
, bytes
int) error
{
169 return syscall
.EPLAN9
172 func setWriteBuffer(fd
*netFD
, bytes
int) error
{
173 return syscall
.EPLAN9