Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(324)

Side by Side Diff: src/pkg/net/tcpsock_posix.go

Issue 6525048: code review 6525048: net: protocol specific listen functions return a proper... (Closed)
Patch Set: diff -r 0b46d6fe2f1c https://go.googlecode.com/hg/ Created 11 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pkg/net/tcpsock_plan9.go ('k') | src/pkg/net/udp_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // +build darwin freebsd linux netbsd openbsd windows 5 // +build darwin freebsd linux netbsd openbsd windows
6 6
7 // TCP sockets 7 // TCP sockets
8 8
9 package net 9 package net
10 10
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 if !c.ok() { 136 if !c.ok() {
137 return syscall.EINVAL 137 return syscall.EINVAL
138 } 138 }
139 return setNoDelay(c.fd, noDelay) 139 return setNoDelay(c.fd, noDelay)
140 } 140 }
141 141
142 // DialTCP connects to the remote address raddr on the network net, 142 // DialTCP connects to the remote address raddr on the network net,
143 // which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is used 143 // which must be "tcp", "tcp4", or "tcp6". If laddr is not nil, it is used
144 // as the local address for the connection. 144 // as the local address for the connection.
145 func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) { 145 func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) {
146 switch net {
147 case "tcp", "tcp4", "tcp6":
148 default:
149 return nil, UnknownNetworkError(net)
150 }
151 if raddr == nil {
152 return nil, &OpError{"dial", net, nil, errMissingAddress}
153 }
146 return dialTCP(net, laddr, raddr, noDeadline) 154 return dialTCP(net, laddr, raddr, noDeadline)
147 } 155 }
148 156
149 func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, e rror) { 157 func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, e rror) {
150 if raddr == nil {
151 return nil, &OpError{"dial", net, nil, errMissingAddress}
152 }
153
154 fd, err := internetSocket(net, laddr.toAddr(), raddr.toAddr(), deadline, syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP) 158 fd, err := internetSocket(net, laddr.toAddr(), raddr.toAddr(), deadline, syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP)
155 159
156 // TCP has a rarely used mechanism called a 'simultaneous connection' in 160 // TCP has a rarely used mechanism called a 'simultaneous connection' in
157 // which Dial("tcp", addr1, addr2) run on the machine at addr1 can 161 // which Dial("tcp", addr1, addr2) run on the machine at addr1 can
158 // connect to a simultaneous Dial("tcp", addr2, addr1) run on the machin e 162 // connect to a simultaneous Dial("tcp", addr2, addr1) run on the machin e
159 // at addr2, without either machine executing Listen. If laddr == nil, 163 // at addr2, without either machine executing Listen. If laddr == nil,
160 // it means we want the kernel to pick an appropriate originating local 164 // it means we want the kernel to pick an appropriate originating local
161 // address. Some Linux kernels cycle blindly through a fixed range of 165 // address. Some Linux kernels cycle blindly through a fixed range of
162 // local ports, regardless of destination port. If a kernel happens to 166 // local ports, regardless of destination port. If a kernel happens to
163 // pick local port 50001 as the source for a Dial("tcp", "", "localhost: 50001"), 167 // pick local port 50001 as the source for a Dial("tcp", "", "localhost: 50001"),
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 return ok && e.Err == syscall.EADDRNOTAVAIL 221 return ok && e.Err == syscall.EADDRNOTAVAIL
218 } 222 }
219 223
220 // TCPListener is a TCP network listener. 224 // TCPListener is a TCP network listener.
221 // Clients should typically use variables of type Listener 225 // Clients should typically use variables of type Listener
222 // instead of assuming TCP. 226 // instead of assuming TCP.
223 type TCPListener struct { 227 type TCPListener struct {
224 fd *netFD 228 fd *netFD
225 } 229 }
226 230
227 // ListenTCP announces on the TCP address laddr and returns a TCP listener.
228 // Net must be "tcp", "tcp4", or "tcp6".
229 // If laddr has a port of 0, it means to listen on some available port.
230 // The caller can use l.Addr() to retrieve the chosen address.
231 func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) {
232 fd, err := internetSocket(net, laddr.toAddr(), nil, noDeadline, syscall. SOCK_STREAM, 0, "listen", sockaddrToTCP)
233 if err != nil {
234 return nil, err
235 }
236 err = syscall.Listen(fd.sysfd, listenerBacklog)
237 if err != nil {
238 closesocket(fd.sysfd)
239 return nil, &OpError{"listen", net, laddr, err}
240 }
241 l := new(TCPListener)
242 l.fd = fd
243 return l, nil
244 }
245
246 // AcceptTCP accepts the next incoming call and returns the new connection 231 // AcceptTCP accepts the next incoming call and returns the new connection
247 // and the remote address. 232 // and the remote address.
248 func (l *TCPListener) AcceptTCP() (c *TCPConn, err error) { 233 func (l *TCPListener) AcceptTCP() (c *TCPConn, err error) {
249 if l == nil || l.fd == nil || l.fd.sysfd < 0 { 234 if l == nil || l.fd == nil || l.fd.sysfd < 0 {
250 return nil, syscall.EINVAL 235 return nil, syscall.EINVAL
251 } 236 }
252 fd, err := l.fd.accept(sockaddrToTCP) 237 fd, err := l.fd.accept(sockaddrToTCP)
253 if err != nil { 238 if err != nil {
254 return nil, err 239 return nil, err
255 } 240 }
(...skipping 28 matching lines...) Expand all
284 if l == nil || l.fd == nil { 269 if l == nil || l.fd == nil {
285 return syscall.EINVAL 270 return syscall.EINVAL
286 } 271 }
287 return setDeadline(l.fd, t) 272 return setDeadline(l.fd, t)
288 } 273 }
289 274
290 // File returns a copy of the underlying os.File, set to blocking mode. 275 // File returns a copy of the underlying os.File, set to blocking mode.
291 // It is the caller's responsibility to close f when finished. 276 // It is the caller's responsibility to close f when finished.
292 // Closing l does not affect f, and closing f does not affect l. 277 // Closing l does not affect f, and closing f does not affect l.
293 func (l *TCPListener) File() (f *os.File, err error) { return l.fd.dup() } 278 func (l *TCPListener) File() (f *os.File, err error) { return l.fd.dup() }
279
280 // ListenTCP announces on the TCP address laddr and returns a TCP listener.
281 // Net must be "tcp", "tcp4", or "tcp6".
282 // If laddr has a port of 0, it means to listen on some available port.
283 // The caller can use l.Addr() to retrieve the chosen address.
284 func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) {
285 switch net {
286 case "tcp", "tcp4", "tcp6":
287 default:
288 return nil, UnknownNetworkError(net)
289 }
290 if laddr == nil {
291 laddr = &TCPAddr{}
292 }
293 fd, err := internetSocket(net, laddr.toAddr(), nil, noDeadline, syscall. SOCK_STREAM, 0, "listen", sockaddrToTCP)
294 if err != nil {
295 return nil, err
296 }
297 err = syscall.Listen(fd.sysfd, listenerBacklog)
298 if err != nil {
299 closesocket(fd.sysfd)
300 return nil, &OpError{"listen", net, laddr, err}
301 }
302 l := new(TCPListener)
303 l.fd = fd
304 return l, nil
305 }
OLDNEW
« no previous file with comments | « src/pkg/net/tcpsock_plan9.go ('k') | src/pkg/net/udp_test.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b