fdmu fdMutex
// immutable until Close
- net string
- n string
- dir string
- ctl, data *os.File
- laddr, raddr Addr
+ net string
+ n string
+ dir string
+ listen, ctl, data *os.File
+ laddr, raddr Addr
}
var (
netdir = "/net"
}
-func newFD(net, name string, ctl, data *os.File, laddr, raddr Addr) (*netFD, error) {
- return &netFD{net: net, n: name, dir: netdir + "/" + net + "/" + name, ctl: ctl, data: data, laddr: laddr, raddr: raddr}, nil
+func newFD(net, name string, listen, ctl, data *os.File, laddr, raddr Addr) (*netFD, error) {
+ return &netFD{
+ net: net,
+ n: name,
+ dir: netdir + "/" + net + "/" + name,
+ listen: listen,
+ ctl: ctl, data: data,
+ laddr: laddr,
+ raddr: raddr,
+ }, nil
}
func (fd *netFD) init() error {
err = err1
}
}
+ if fd.listen != nil {
+ if err1 := fd.listen.Close(); err1 != nil && err == nil {
+ err = err1
+ }
+ }
fd.ctl = nil
fd.data = nil
+ fd.listen = nil
}
func (fd *netFD) Read(b []byte) (n int, err error) {
}
if fd.net == "tcp" {
// The following line is required to unblock Reads.
- // For some reason, WriteString returns an error:
- // "write /net/tcp/39/listen: inappropriate use of fd"
- // But without it, Reads on dead conns hang forever.
- // See Issue 9554.
- fd.ctl.WriteString("close")
+ _, err := fd.ctl.WriteString("close")
+ if err != nil {
+ return err
+ }
}
err := fd.ctl.Close()
if fd.data != nil {
err = err1
}
}
+ if fd.listen != nil {
+ if err1 := fd.listen.Close(); err1 != nil && err == nil {
+ err = err1
+ }
+ }
fd.ctl = nil
fd.data = nil
+ fd.listen = nil
return err
}
f.Close()
return nil, err
}
- return newFD(proto, name, f, data, laddr, raddr)
+ return newFD(proto, name, nil, f, data, laddr, raddr)
}
func listenPlan9(ctx context.Context, net string, laddr Addr) (fd *netFD, err error) {
f.Close()
return nil, err
}
- return newFD(proto, name, f, nil, laddr, nil)
+ return newFD(proto, name, nil, f, nil, laddr, nil)
}
func (fd *netFD) netFD() (*netFD, error) {
- return newFD(fd.net, fd.n, fd.ctl, fd.data, fd.laddr, fd.raddr)
+ return newFD(fd.net, fd.n, fd.listen, fd.ctl, fd.data, fd.laddr, fd.raddr)
}
func (fd *netFD) acceptPlan9() (nfd *netFD, err error) {
return nil, err
}
defer fd.readUnlock()
- f, err := os.Open(fd.dir + "/listen")
+ listen, err := os.Open(fd.dir + "/listen")
if err != nil {
return nil, err
}
var buf [16]byte
- n, err := f.Read(buf[:])
+ n, err := listen.Read(buf[:])
if err != nil {
- f.Close()
+ listen.Close()
return nil, err
}
name := string(buf[:n])
+ ctl, err := os.OpenFile(netdir+"/"+fd.net+"/"+name+"/ctl", os.O_RDWR, 0)
+ if err != nil {
+ listen.Close()
+ return nil, err
+ }
data, err := os.OpenFile(netdir+"/"+fd.net+"/"+name+"/data", os.O_RDWR, 0)
if err != nil {
- f.Close()
+ listen.Close()
+ ctl.Close()
return nil, err
}
raddr, err := readPlan9Addr(fd.net, netdir+"/"+fd.net+"/"+name+"/remote")
if err != nil {
+ listen.Close()
+ ctl.Close()
data.Close()
- f.Close()
return nil, err
}
- return newFD(fd.net, name, f, data, fd.laddr, raddr)
+ return newFD(fd.net, name, listen, ctl, data, fd.laddr, raddr)
}