[52/77] Use scalar_int_mode in extract/store_bit_field
[official-gcc.git] / libgo / go / net / tcpsock.go
blob69731ebc9143c4f7d869727bda19203a03546277
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 package net
7 import (
8 "context"
9 "io"
10 "os"
11 "syscall"
12 "time"
15 // BUG(mikio): On Windows, the File method of TCPListener is not
16 // implemented.
18 // TCPAddr represents the address of a TCP end point.
19 type TCPAddr struct {
20 IP IP
21 Port int
22 Zone string // IPv6 scoped addressing zone
25 // Network returns the address's network name, "tcp".
26 func (a *TCPAddr) Network() string { return "tcp" }
28 func (a *TCPAddr) String() string {
29 if a == nil {
30 return "<nil>"
32 ip := ipEmptyString(a.IP)
33 if a.Zone != "" {
34 return JoinHostPort(ip+"%"+a.Zone, itoa(a.Port))
36 return JoinHostPort(ip, itoa(a.Port))
39 func (a *TCPAddr) isWildcard() bool {
40 if a == nil || a.IP == nil {
41 return true
43 return a.IP.IsUnspecified()
46 func (a *TCPAddr) opAddr() Addr {
47 if a == nil {
48 return nil
50 return a
53 // ResolveTCPAddr parses addr as a TCP address of the form "host:port"
54 // or "[ipv6-host%zone]:port" and resolves a pair of domain name and
55 // port name on the network net, which must be "tcp", "tcp4" or
56 // "tcp6". A literal address or host name for IPv6 must be enclosed
57 // in square brackets, as in "[::1]:80", "[ipv6-host]:http" or
58 // "[ipv6-host%zone]:80".
60 // Resolving a hostname is not recommended because this returns at most
61 // one of its IP addresses.
62 func ResolveTCPAddr(net, addr string) (*TCPAddr, error) {
63 switch net {
64 case "tcp", "tcp4", "tcp6":
65 case "": // a hint wildcard for Go 1.0 undocumented behavior
66 net = "tcp"
67 default:
68 return nil, UnknownNetworkError(net)
70 addrs, err := DefaultResolver.internetAddrList(context.Background(), net, addr)
71 if err != nil {
72 return nil, err
74 return addrs.first(isIPv4).(*TCPAddr), nil
77 // TCPConn is an implementation of the Conn interface for TCP network
78 // connections.
79 type TCPConn struct {
80 conn
83 // ReadFrom implements the io.ReaderFrom ReadFrom method.
84 func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
85 if !c.ok() {
86 return 0, syscall.EINVAL
88 n, err := c.readFrom(r)
89 if err != nil && err != io.EOF {
90 err = &OpError{Op: "readfrom", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
92 return n, err
95 // CloseRead shuts down the reading side of the TCP connection.
96 // Most callers should just use Close.
97 func (c *TCPConn) CloseRead() error {
98 if !c.ok() {
99 return syscall.EINVAL
101 if err := c.fd.closeRead(); err != nil {
102 return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
104 return nil
107 // CloseWrite shuts down the writing side of the TCP connection.
108 // Most callers should just use Close.
109 func (c *TCPConn) CloseWrite() error {
110 if !c.ok() {
111 return syscall.EINVAL
113 if err := c.fd.closeWrite(); err != nil {
114 return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
116 return nil
119 // SetLinger sets the behavior of Close on a connection which still
120 // has data waiting to be sent or to be acknowledged.
122 // If sec < 0 (the default), the operating system finishes sending the
123 // data in the background.
125 // If sec == 0, the operating system discards any unsent or
126 // unacknowledged data.
128 // If sec > 0, the data is sent in the background as with sec < 0. On
129 // some operating systems after sec seconds have elapsed any remaining
130 // unsent data may be discarded.
131 func (c *TCPConn) SetLinger(sec int) error {
132 if !c.ok() {
133 return syscall.EINVAL
135 if err := setLinger(c.fd, sec); err != nil {
136 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
138 return nil
141 // SetKeepAlive sets whether the operating system should send
142 // keepalive messages on the connection.
143 func (c *TCPConn) SetKeepAlive(keepalive bool) error {
144 if !c.ok() {
145 return syscall.EINVAL
147 if err := setKeepAlive(c.fd, keepalive); err != nil {
148 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
150 return nil
153 // SetKeepAlivePeriod sets period between keep alives.
154 func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error {
155 if !c.ok() {
156 return syscall.EINVAL
158 if err := setKeepAlivePeriod(c.fd, d); err != nil {
159 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
161 return nil
164 // SetNoDelay controls whether the operating system should delay
165 // packet transmission in hopes of sending fewer packets (Nagle's
166 // algorithm). The default is true (no delay), meaning that data is
167 // sent as soon as possible after a Write.
168 func (c *TCPConn) SetNoDelay(noDelay bool) error {
169 if !c.ok() {
170 return syscall.EINVAL
172 if err := setNoDelay(c.fd, noDelay); err != nil {
173 return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
175 return nil
178 func newTCPConn(fd *netFD) *TCPConn {
179 c := &TCPConn{conn{fd}}
180 setNoDelay(c.fd, true)
181 return c
184 // DialTCP connects to the remote address raddr on the network net,
185 // which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is
186 // used as the local address for the connection.
187 func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) {
188 switch net {
189 case "tcp", "tcp4", "tcp6":
190 default:
191 return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(net)}
193 if raddr == nil {
194 return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
196 c, err := dialTCP(context.Background(), net, laddr, raddr)
197 if err != nil {
198 return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
200 return c, nil
203 // TCPListener is a TCP network listener. Clients should typically
204 // use variables of type Listener instead of assuming TCP.
205 type TCPListener struct {
206 fd *netFD
209 // AcceptTCP accepts the next incoming call and returns the new
210 // connection.
211 func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
212 if !l.ok() {
213 return nil, syscall.EINVAL
215 c, err := l.accept()
216 if err != nil {
217 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
219 return c, nil
222 // Accept implements the Accept method in the Listener interface; it
223 // waits for the next call and returns a generic Conn.
224 func (l *TCPListener) Accept() (Conn, error) {
225 if !l.ok() {
226 return nil, syscall.EINVAL
228 c, err := l.accept()
229 if err != nil {
230 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
232 return c, nil
235 // Close stops listening on the TCP address.
236 // Already Accepted connections are not closed.
237 func (l *TCPListener) Close() error {
238 if !l.ok() {
239 return syscall.EINVAL
241 if err := l.close(); err != nil {
242 return &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
244 return nil
247 // Addr returns the listener's network address, a *TCPAddr.
248 // The Addr returned is shared by all invocations of Addr, so
249 // do not modify it.
250 func (l *TCPListener) Addr() Addr { return l.fd.laddr }
252 // SetDeadline sets the deadline associated with the listener.
253 // A zero time value disables the deadline.
254 func (l *TCPListener) SetDeadline(t time.Time) error {
255 if !l.ok() {
256 return syscall.EINVAL
258 if err := l.fd.setDeadline(t); err != nil {
259 return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
261 return nil
264 // File returns a copy of the underlying os.File, set to blocking
265 // mode. It is the caller's responsibility to close f when finished.
266 // Closing l does not affect f, and closing f does not affect l.
268 // The returned os.File's file descriptor is different from the
269 // connection's. Attempting to change properties of the original
270 // using this duplicate may or may not have the desired effect.
271 func (l *TCPListener) File() (f *os.File, err error) {
272 if !l.ok() {
273 return nil, syscall.EINVAL
275 f, err = l.file()
276 if err != nil {
277 return nil, &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
279 return
282 // ListenTCP announces on the TCP address laddr and returns a TCP
283 // listener. Net must be "tcp", "tcp4", or "tcp6". If laddr has a
284 // port of 0, ListenTCP will choose an available port. The caller can
285 // use the Addr method of TCPListener to retrieve the chosen address.
286 func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) {
287 switch net {
288 case "tcp", "tcp4", "tcp6":
289 default:
290 return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(net)}
292 if laddr == nil {
293 laddr = &TCPAddr{}
295 ln, err := listenTCP(context.Background(), net, laddr)
296 if err != nil {
297 return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: err}
299 return ln, nil