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.
5 // TCP sockets for Plan 9
16 // TCPConn is an implementation of the Conn interface for TCP network
22 func newTCPConn(fd
*netFD
) *TCPConn
{
23 return &TCPConn
{conn
{fd
}}
26 // ReadFrom implements the io.ReaderFrom ReadFrom method.
27 func (c
*TCPConn
) ReadFrom(r io
.Reader
) (int64, error
) {
28 return genericReadFrom(c
, r
)
31 // CloseRead shuts down the reading side of the TCP connection.
32 // Most callers should just use Close.
33 func (c
*TCPConn
) CloseRead() error
{
37 return c
.fd
.CloseRead()
40 // CloseWrite shuts down the writing side of the TCP connection.
41 // Most callers should just use Close.
42 func (c
*TCPConn
) CloseWrite() error
{
46 return c
.fd
.CloseWrite()
49 // SetLinger sets the behavior of Close() on a connection which still
50 // has data waiting to be sent or to be acknowledged.
52 // If sec < 0 (the default), Close returns immediately and the
53 // operating system finishes sending the data in the background.
55 // If sec == 0, Close returns immediately and the operating system
56 // discards any unsent or unacknowledged data.
58 // If sec > 0, Close blocks for at most sec seconds waiting for data
59 // to be sent and acknowledged.
60 func (c
*TCPConn
) SetLinger(sec
int) error
{
64 // SetKeepAlive sets whether the operating system should send
65 // keepalive messages on the connection.
66 func (c
*TCPConn
) SetKeepAlive(keepalive
bool) error
{
70 // SetNoDelay controls whether the operating system should delay
71 // packet transmission in hopes of sending fewer packets (Nagle's
72 // algorithm). The default is true (no delay), meaning that data is
73 // sent as soon as possible after a Write.
74 func (c
*TCPConn
) SetNoDelay(noDelay
bool) error
{
78 // DialTCP connects to the remote address raddr on the network net,
79 // which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is
80 // used as the local address for the connection.
81 func DialTCP(net
string, laddr
, raddr
*TCPAddr
) (*TCPConn
, error
) {
82 return dialTCP(net
, laddr
, raddr
, noDeadline
)
85 func dialTCP(net
string, laddr
, raddr
*TCPAddr
, deadline time
.Time
) (*TCPConn
, error
) {
86 if !deadline
.IsZero() {
87 panic("net.dialTCP: deadline not implemented on Plan 9")
90 case "tcp", "tcp4", "tcp6":
92 return nil, UnknownNetworkError(net
)
95 return nil, &OpError
{"dial", net
, nil, errMissingAddress
}
97 fd
, err
:= dialPlan9(net
, laddr
, raddr
)
101 return &TCPConn
{conn
{fd
}}, nil
104 // TCPListener is a TCP network listener. Clients should typically
105 // use variables of type Listener instead of assuming TCP.
106 type TCPListener
struct {
110 // AcceptTCP accepts the next incoming call and returns the new
111 // connection and the remote address.
112 func (l
*TCPListener
) AcceptTCP() (*TCPConn
, error
) {
113 if l
== nil || l
.fd
== nil || l
.fd
.ctl
== nil {
114 return nil, syscall
.EINVAL
116 fd
, err
:= l
.fd
.acceptPlan9()
120 return newTCPConn(fd
), nil
123 // Accept implements the Accept method in the Listener interface; it
124 // waits for the next call and returns a generic Conn.
125 func (l
*TCPListener
) Accept() (Conn
, error
) {
126 if l
== nil || l
.fd
== nil || l
.fd
.ctl
== nil {
127 return nil, syscall
.EINVAL
129 c
, err
:= l
.AcceptTCP()
136 // Close stops listening on the TCP address.
137 // Already Accepted connections are not closed.
138 func (l
*TCPListener
) Close() error
{
139 if l
== nil || l
.fd
== nil || l
.fd
.ctl
== nil {
140 return syscall
.EINVAL
142 if _
, err
:= l
.fd
.ctl
.WriteString("hangup"); err
!= nil {
146 return l
.fd
.ctl
.Close()
149 // Addr returns the listener's network address, a *TCPAddr.
150 func (l
*TCPListener
) Addr() Addr
{ return l
.fd
.laddr
}
152 // SetDeadline sets the deadline associated with the listener.
153 // A zero time value disables the deadline.
154 func (l
*TCPListener
) SetDeadline(t time
.Time
) error
{
155 if l
== nil || l
.fd
== nil || l
.fd
.ctl
== nil {
156 return syscall
.EINVAL
158 return setDeadline(l
.fd
, t
)
161 // File returns a copy of the underlying os.File, set to blocking
162 // mode. It is the caller's responsibility to close f when finished.
163 // Closing l does not affect f, and closing f does not affect l.
164 func (l
*TCPListener
) File() (f
*os
.File
, err error
) { return l
.fd
.dup() }
166 // ListenTCP announces on the TCP address laddr and returns a TCP
167 // listener. Net must be "tcp", "tcp4", or "tcp6". If laddr has a
168 // port of 0, it means to listen on some available port. The caller
169 // can use l.Addr() to retrieve the chosen address.
170 func ListenTCP(net
string, laddr
*TCPAddr
) (*TCPListener
, error
) {
172 case "tcp", "tcp4", "tcp6":
174 return nil, UnknownNetworkError(net
)
179 fd
, err
:= listenPlan9(net
, laddr
)
183 return &TCPListener
{fd
}, nil