2013-02-11 Sebastian Huber <sebastian.huber@embedded-brains.de>
[official-gcc.git] / libgo / go / net / tcpsock_plan9.go
blob954c99a2d8191347f0adee34d07dd5e8822cdbbf
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
7 package net
9 import (
10 "io"
11 "os"
12 "syscall"
13 "time"
16 // TCPConn is an implementation of the Conn interface for TCP network
17 // connections.
18 type TCPConn struct {
19 conn
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 {
34 if !c.ok() {
35 return syscall.EINVAL
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 {
43 if !c.ok() {
44 return syscall.EINVAL
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 {
61 return syscall.EPLAN9
64 // SetKeepAlive sets whether the operating system should send
65 // keepalive messages on the connection.
66 func (c *TCPConn) SetKeepAlive(keepalive bool) error {
67 return syscall.EPLAN9
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 {
75 return syscall.EPLAN9
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")
89 switch net {
90 case "tcp", "tcp4", "tcp6":
91 default:
92 return nil, UnknownNetworkError(net)
94 if raddr == nil {
95 return nil, &OpError{"dial", net, nil, errMissingAddress}
97 fd, err := dialPlan9(net, laddr, raddr)
98 if err != nil {
99 return nil, err
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 {
107 fd *netFD
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()
117 if err != nil {
118 return nil, err
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()
130 if err != nil {
131 return nil, err
133 return c, nil
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 {
143 l.fd.ctl.Close()
144 return err
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) {
171 switch net {
172 case "tcp", "tcp4", "tcp6":
173 default:
174 return nil, UnknownNetworkError(net)
176 if laddr == nil {
177 laddr = &TCPAddr{}
179 fd, err := listenPlan9(net, laddr)
180 if err != nil {
181 return nil, err
183 return &TCPListener{fd}, nil