...

Source file src/net/fd_plan9.go

     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.
     4	
     5	package net
     6	
     7	import (
     8		"internal/poll"
     9		"io"
    10		"os"
    11		"syscall"
    12		"time"
    13	)
    14	
    15	// Network file descriptor.
    16	type netFD struct {
    17		pfd poll.FD
    18	
    19		// immutable until Close
    20		net               string
    21		n                 string
    22		dir               string
    23		listen, ctl, data *os.File
    24		laddr, raddr      Addr
    25		isStream          bool
    26	}
    27	
    28	var netdir = "/net" // default network
    29	
    30	func newFD(net, name string, listen, ctl, data *os.File, laddr, raddr Addr) (*netFD, error) {
    31		ret := &netFD{
    32			net:    net,
    33			n:      name,
    34			dir:    netdir + "/" + net + "/" + name,
    35			listen: listen,
    36			ctl:    ctl, data: data,
    37			laddr: laddr,
    38			raddr: raddr,
    39		}
    40		ret.pfd.Destroy = ret.destroy
    41		return ret, nil
    42	}
    43	
    44	func (fd *netFD) init() error {
    45		// stub for future fd.pd.Init(fd)
    46		return nil
    47	}
    48	
    49	func (fd *netFD) name() string {
    50		var ls, rs string
    51		if fd.laddr != nil {
    52			ls = fd.laddr.String()
    53		}
    54		if fd.raddr != nil {
    55			rs = fd.raddr.String()
    56		}
    57		return fd.net + ":" + ls + "->" + rs
    58	}
    59	
    60	func (fd *netFD) ok() bool { return fd != nil && fd.ctl != nil }
    61	
    62	func (fd *netFD) destroy() {
    63		if !fd.ok() {
    64			return
    65		}
    66		err := fd.ctl.Close()
    67		if fd.data != nil {
    68			if err1 := fd.data.Close(); err1 != nil && err == nil {
    69				err = err1
    70			}
    71		}
    72		if fd.listen != nil {
    73			if err1 := fd.listen.Close(); err1 != nil && err == nil {
    74				err = err1
    75			}
    76		}
    77		fd.ctl = nil
    78		fd.data = nil
    79		fd.listen = nil
    80	}
    81	
    82	func (fd *netFD) Read(b []byte) (n int, err error) {
    83		if !fd.ok() || fd.data == nil {
    84			return 0, syscall.EINVAL
    85		}
    86		n, err = fd.pfd.Read(fd.data.Read, b)
    87		if fd.net == "udp" && err == io.EOF {
    88			n = 0
    89			err = nil
    90		}
    91		return
    92	}
    93	
    94	func (fd *netFD) Write(b []byte) (n int, err error) {
    95		if !fd.ok() || fd.data == nil {
    96			return 0, syscall.EINVAL
    97		}
    98		return fd.pfd.Write(fd.data.Write, b)
    99	}
   100	
   101	func (fd *netFD) closeRead() error {
   102		if !fd.ok() {
   103			return syscall.EINVAL
   104		}
   105		return syscall.EPLAN9
   106	}
   107	
   108	func (fd *netFD) closeWrite() error {
   109		if !fd.ok() {
   110			return syscall.EINVAL
   111		}
   112		return syscall.EPLAN9
   113	}
   114	
   115	func (fd *netFD) Close() error {
   116		if err := fd.pfd.Close(); err != nil {
   117			return err
   118		}
   119		if !fd.ok() {
   120			return syscall.EINVAL
   121		}
   122		if fd.net == "tcp" {
   123			// The following line is required to unblock Reads.
   124			_, err := fd.ctl.WriteString("close")
   125			if err != nil {
   126				return err
   127			}
   128		}
   129		err := fd.ctl.Close()
   130		if fd.data != nil {
   131			if err1 := fd.data.Close(); err1 != nil && err == nil {
   132				err = err1
   133			}
   134		}
   135		if fd.listen != nil {
   136			if err1 := fd.listen.Close(); err1 != nil && err == nil {
   137				err = err1
   138			}
   139		}
   140		fd.ctl = nil
   141		fd.data = nil
   142		fd.listen = nil
   143		return err
   144	}
   145	
   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
   150		}
   151		return fd.file(fd.data, fd.dir+"/data")
   152	}
   153	
   154	func (l *TCPListener) dup() (*os.File, error) {
   155		if !l.fd.ok() {
   156			return nil, syscall.EINVAL
   157		}
   158		return l.fd.file(l.fd.ctl, l.fd.dir+"/ctl")
   159	}
   160	
   161	func (fd *netFD) file(f *os.File, s string) (*os.File, error) {
   162		dfd, err := syscall.Dup(int(f.Fd()), -1)
   163		if err != nil {
   164			return nil, os.NewSyscallError("dup", err)
   165		}
   166		return os.NewFile(uintptr(dfd), s), nil
   167	}
   168	
   169	func setReadBuffer(fd *netFD, bytes int) error {
   170		return syscall.EPLAN9
   171	}
   172	
   173	func setWriteBuffer(fd *netFD, bytes int) error {
   174		return syscall.EPLAN9
   175	}
   176	
   177	func (fd *netFD) SetDeadline(t time.Time) error {
   178		return fd.pfd.SetDeadline(t)
   179	}
   180	
   181	func (fd *netFD) SetReadDeadline(t time.Time) error {
   182		return fd.pfd.SetReadDeadline(t)
   183	}
   184	
   185	func (fd *netFD) SetWriteDeadline(t time.Time) error {
   186		return fd.pfd.SetWriteDeadline(t)
   187	}
   188	

View as plain text