1
0
mirror of https://github.com/golang/go synced 2024-10-05 05:11:25 -06:00
go/src/net/fd_plan9.go
Mikio Hara ac2f84d524 net: make unexposed methods start with lowercase letters
This change makes unexposed methods start with lowercase letters for
avoiding unnecessary confusion because the net package uses many
embedding structures and intrefaces for controlling exposure of APIs.

Note that this change leaves DNS-related methods as they are.

Change-Id: I253758d1659175c5d0af6b2efcd30ce83f46543d
Reviewed-on: https://go-review.googlesource.com/20784
Run-TryBot: Mikio Hara <mikioh.mikioh@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-17 21:43:41 +00:00

237 lines
4.8 KiB
Go

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package net
import (
"io"
"os"
"syscall"
"time"
)
// Network file descriptor.
type netFD struct {
// locking/lifetime of sysfd + serialize access to Read and Write methods
fdmu fdMutex
// immutable until Close
net string
n string
dir string
ctl, data *os.File
laddr, raddr Addr
}
var (
netdir string // default network
)
func sysInit() {
netdir = "/net"
}
func dial(net string, ra Addr, dialer func(time.Time) (Conn, error), deadline time.Time) (Conn, error) {
// On plan9, use the relatively inefficient
// goroutine-racing implementation.
return dialChannel(net, ra, dialer, deadline)
}
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 (fd *netFD) init() error {
// stub for future fd.pd.Init(fd)
return nil
}
func (fd *netFD) name() string {
var ls, rs string
if fd.laddr != nil {
ls = fd.laddr.String()
}
if fd.raddr != nil {
rs = fd.raddr.String()
}
return fd.net + ":" + ls + "->" + rs
}
func (fd *netFD) ok() bool { return fd != nil && fd.ctl != nil }
func (fd *netFD) destroy() {
if !fd.ok() {
return
}
err := fd.ctl.Close()
if fd.data != nil {
if err1 := fd.data.Close(); err1 != nil && err == nil {
err = err1
}
}
fd.ctl = nil
fd.data = nil
}
// Add a reference to this fd.
// Returns an error if the fd cannot be used.
func (fd *netFD) incref() error {
if !fd.fdmu.incref() {
return errClosing
}
return nil
}
// Remove a reference to this FD and close if we've been asked to do so
// (and there are no references left).
func (fd *netFD) decref() {
if fd.fdmu.decref() {
fd.destroy()
}
}
// Add a reference to this fd and lock for reading.
// Returns an error if the fd cannot be used.
func (fd *netFD) readLock() error {
if !fd.fdmu.rwlock(true) {
return errClosing
}
return nil
}
// Unlock for reading and remove a reference to this FD.
func (fd *netFD) readUnlock() {
if fd.fdmu.rwunlock(true) {
fd.destroy()
}
}
// Add a reference to this fd and lock for writing.
// Returns an error if the fd cannot be used.
func (fd *netFD) writeLock() error {
if !fd.fdmu.rwlock(false) {
return errClosing
}
return nil
}
// Unlock for writing and remove a reference to this FD.
func (fd *netFD) writeUnlock() {
if fd.fdmu.rwunlock(false) {
fd.destroy()
}
}
func (fd *netFD) Read(b []byte) (n int, err error) {
if !fd.ok() || fd.data == nil {
return 0, syscall.EINVAL
}
if err := fd.readLock(); err != nil {
return 0, err
}
defer fd.readUnlock()
n, err = fd.data.Read(b)
if fd.net == "udp" && err == io.EOF {
n = 0
err = nil
}
return
}
func (fd *netFD) Write(b []byte) (n int, err error) {
if !fd.ok() || fd.data == nil {
return 0, syscall.EINVAL
}
if err := fd.writeLock(); err != nil {
return 0, err
}
defer fd.writeUnlock()
return fd.data.Write(b)
}
func (fd *netFD) closeRead() error {
if !fd.ok() {
return syscall.EINVAL
}
return syscall.EPLAN9
}
func (fd *netFD) closeWrite() error {
if !fd.ok() {
return syscall.EINVAL
}
return syscall.EPLAN9
}
func (fd *netFD) Close() error {
if !fd.fdmu.increfAndClose() {
return errClosing
}
if !fd.ok() {
return syscall.EINVAL
}
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("hangup")
}
err := fd.ctl.Close()
if fd.data != nil {
if err1 := fd.data.Close(); err1 != nil && err == nil {
err = err1
}
}
fd.ctl = nil
fd.data = nil
return err
}
// This method is only called via Conn.
func (fd *netFD) dup() (*os.File, error) {
if !fd.ok() || fd.data == nil {
return nil, syscall.EINVAL
}
return fd.file(fd.data, fd.dir+"/data")
}
func (l *TCPListener) dup() (*os.File, error) {
if !l.fd.ok() {
return nil, syscall.EINVAL
}
return l.fd.file(l.fd.ctl, l.fd.dir+"/ctl")
}
func (fd *netFD) file(f *os.File, s string) (*os.File, error) {
syscall.ForkLock.RLock()
dfd, err := syscall.Dup(int(f.Fd()), -1)
syscall.ForkLock.RUnlock()
if err != nil {
return nil, os.NewSyscallError("dup", err)
}
return os.NewFile(uintptr(dfd), s), nil
}
func (fd *netFD) setDeadline(t time.Time) error {
return syscall.EPLAN9
}
func (fd *netFD) setReadDeadline(t time.Time) error {
return syscall.EPLAN9
}
func (fd *netFD) setWriteDeadline(t time.Time) error {
return syscall.EPLAN9
}
func setReadBuffer(fd *netFD, bytes int) error {
return syscall.EPLAN9
}
func setWriteBuffer(fd *netFD, bytes int) error {
return syscall.EPLAN9
}