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
// +build darwin freebsd linux netbsd openbsd
17
// Network file descriptor.
19
// locking/lifetime of sysfd
23
// must lock both sysmu and pollDesc to write
24
// can lock either to read
27
// immutable until Close
37
// serialize access to Read and Write methods
44
func resolveAndDial(net, addr string, localAddr Addr, deadline time.Time) (Conn, error) {
45
ra, err := resolveAddr("dial", net, addr, deadline)
49
return dial(net, addr, localAddr, ra, deadline)
52
func newFD(fd, family, sotype int, net string) (*netFD, error) {
59
if err := netfd.pd.Init(netfd); err != nil {
65
func (fd *netFD) setAddr(laddr, raddr Addr) {
68
fd.sysfile = os.NewFile(uintptr(fd.sysfd), fd.net)
71
func (fd *netFD) name() string {
74
ls = fd.laddr.String()
77
rs = fd.raddr.String()
79
return fd.net + ":" + ls + "->" + rs
82
func (fd *netFD) connect(la, ra syscall.Sockaddr) error {
85
if err := fd.pd.PrepareWrite(); err != nil {
89
err := syscall.Connect(fd.sysfd, ra)
90
if err == nil || err == syscall.EISCONN {
93
if err != syscall.EINPROGRESS && err != syscall.EALREADY && err != syscall.EINTR {
96
if err = fd.pd.WaitWrite(); err != nil {
103
// Add a reference to this fd.
104
// If closing==true, pollDesc must be locked; mark the fd as closing.
105
// Returns an error if the fd cannot be used.
106
func (fd *netFD) incref(closing bool) error {
120
// Remove a reference to this FD and close if we've been asked to do so (and
121
// there are no references left.
122
func (fd *netFD) decref() {
125
if fd.closing && fd.sysref == 0 {
126
// Poller may want to unregister fd in readiness notification mechanism,
127
// so this must be executed before sysfile.Close().
129
if fd.sysfile != nil {
133
closesocket(fd.sysfd)
140
func (fd *netFD) Close() error {
141
fd.pd.Lock() // needed for both fd.incref(true) and pollDesc.Evict
142
if err := fd.incref(true); err != nil {
146
// Unblock any I/O. Once it all unblocks and returns,
147
// so that it cannot be referring to fd.sysfd anymore,
148
// the final decref will close fd.sysfd. This should happen
149
// fairly quickly, since all the I/O is non-blocking, and any
150
// attempts to block in the pollDesc will return errClosing.
151
doWakeup := fd.pd.Evict()
160
func (fd *netFD) shutdown(how int) error {
161
if err := fd.incref(false); err != nil {
165
err := syscall.Shutdown(fd.sysfd, how)
167
return &OpError{"shutdown", fd.net, fd.laddr, err}
172
func (fd *netFD) CloseRead() error {
173
return fd.shutdown(syscall.SHUT_RD)
176
func (fd *netFD) CloseWrite() error {
177
return fd.shutdown(syscall.SHUT_WR)
180
func (fd *netFD) Read(p []byte) (n int, err error) {
182
defer fd.rio.Unlock()
183
if err := fd.incref(false); err != nil {
187
if err := fd.pd.PrepareRead(); err != nil {
188
return 0, &OpError{"read", fd.net, fd.raddr, err}
191
n, err = syscall.Read(int(fd.sysfd), p)
194
if err == syscall.EAGAIN {
195
if err = fd.pd.WaitRead(); err == nil {
200
err = chkReadErr(n, err, fd)
203
if err != nil && err != io.EOF {
204
err = &OpError{"read", fd.net, fd.raddr, err}
209
func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
211
defer fd.rio.Unlock()
212
if err := fd.incref(false); err != nil {
216
if err := fd.pd.PrepareRead(); err != nil {
217
return 0, nil, &OpError{"read", fd.net, fd.laddr, err}
220
n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0)
223
if err == syscall.EAGAIN {
224
if err = fd.pd.WaitRead(); err == nil {
229
err = chkReadErr(n, err, fd)
232
if err != nil && err != io.EOF {
233
err = &OpError{"read", fd.net, fd.laddr, err}
238
func (fd *netFD) ReadMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
240
defer fd.rio.Unlock()
241
if err := fd.incref(false); err != nil {
242
return 0, 0, 0, nil, err
245
if err := fd.pd.PrepareRead(); err != nil {
246
return 0, 0, 0, nil, &OpError{"read", fd.net, fd.laddr, err}
249
n, oobn, flags, sa, err = syscall.Recvmsg(fd.sysfd, p, oob, 0)
251
// TODO(dfc) should n and oobn be set to 0
252
if err == syscall.EAGAIN {
253
if err = fd.pd.WaitRead(); err == nil {
258
err = chkReadErr(n, err, fd)
261
if err != nil && err != io.EOF {
262
err = &OpError{"read", fd.net, fd.laddr, err}
267
func chkReadErr(n int, err error, fd *netFD) error {
268
if n == 0 && err == nil && fd.sotype != syscall.SOCK_DGRAM && fd.sotype != syscall.SOCK_RAW {
274
func (fd *netFD) Write(p []byte) (nn int, err error) {
276
defer fd.wio.Unlock()
277
if err := fd.incref(false); err != nil {
281
if err := fd.pd.PrepareWrite(); err != nil {
282
return 0, &OpError{"write", fd.net, fd.raddr, err}
286
n, err = syscall.Write(int(fd.sysfd), p[nn:])
293
if err == syscall.EAGAIN {
294
if err = fd.pd.WaitWrite(); err == nil {
303
err = io.ErrUnexpectedEOF
308
err = &OpError{"write", fd.net, fd.raddr, err}
313
func (fd *netFD) WriteTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
315
defer fd.wio.Unlock()
316
if err := fd.incref(false); err != nil {
320
if err := fd.pd.PrepareWrite(); err != nil {
321
return 0, &OpError{"write", fd.net, fd.raddr, err}
324
err = syscall.Sendto(fd.sysfd, p, 0, sa)
325
if err == syscall.EAGAIN {
326
if err = fd.pd.WaitWrite(); err == nil {
335
err = &OpError{"write", fd.net, fd.raddr, err}
340
func (fd *netFD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
342
defer fd.wio.Unlock()
343
if err := fd.incref(false); err != nil {
347
if err := fd.pd.PrepareWrite(); err != nil {
348
return 0, 0, &OpError{"write", fd.net, fd.raddr, err}
351
err = syscall.Sendmsg(fd.sysfd, p, oob, sa, 0)
352
if err == syscall.EAGAIN {
353
if err = fd.pd.WaitWrite(); err == nil {
363
err = &OpError{"write", fd.net, fd.raddr, err}
368
func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err error) {
370
defer fd.rio.Unlock()
371
if err := fd.incref(false); err != nil {
377
var rsa syscall.Sockaddr
378
if err = fd.pd.PrepareRead(); err != nil {
379
return nil, &OpError{"accept", fd.net, fd.laddr, err}
382
s, rsa, err = accept(fd.sysfd)
384
if err == syscall.EAGAIN {
385
if err = fd.pd.WaitRead(); err == nil {
388
} else if err == syscall.ECONNABORTED {
389
// This means that a socket on the listen queue was closed
390
// before we Accept()ed it; it's a silly error, so try again.
393
return nil, &OpError{"accept", fd.net, fd.laddr, err}
398
if netfd, err = newFD(s, fd.family, fd.sotype, fd.net); err != nil {
402
lsa, _ := syscall.Getsockname(netfd.sysfd)
403
netfd.setAddr(toAddr(lsa), toAddr(rsa))
407
func (fd *netFD) dup() (f *os.File, err error) {
408
syscall.ForkLock.RLock()
409
ns, err := syscall.Dup(fd.sysfd)
411
syscall.ForkLock.RUnlock()
412
return nil, &OpError{"dup", fd.net, fd.laddr, err}
414
syscall.CloseOnExec(ns)
415
syscall.ForkLock.RUnlock()
417
// We want blocking mode for the new fd, hence the double negative.
418
// This also puts the old fd into blocking mode, meaning that
419
// I/O will block the thread instead of letting us use the epoll server.
420
// Everything will still work, just with more threads.
421
if err = syscall.SetNonblock(ns, false); err != nil {
422
return nil, &OpError{"setnonblock", fd.net, fd.laddr, err}
425
return os.NewFile(uintptr(ns), fd.name()), nil
428
func closesocket(s int) error {
429
return syscall.Close(s)