...
Run Format

Source file src/net/fd_unix.go

     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.
     4	
     5	// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
     6	
     7	package net
     8	
     9	import (
    10		"context"
    11		"io"
    12		"os"
    13		"runtime"
    14		"sync/atomic"
    15		"syscall"
    16	)
    17	
    18	// Network file descriptor.
    19	type netFD struct {
    20		// locking/lifetime of sysfd + serialize access to Read and Write methods
    21		fdmu fdMutex
    22	
    23		// immutable until Close
    24		sysfd       int
    25		family      int
    26		sotype      int
    27		isStream    bool
    28		isConnected bool
    29		net         string
    30		laddr       Addr
    31		raddr       Addr
    32	
    33		// writev cache.
    34		iovecs *[]syscall.Iovec
    35	
    36		// wait server
    37		pd pollDesc
    38	}
    39	
    40	func sysInit() {
    41	}
    42	
    43	func newFD(sysfd, family, sotype int, net string) (*netFD, error) {
    44		return &netFD{sysfd: sysfd, family: family, sotype: sotype, net: net, isStream: sotype == syscall.SOCK_STREAM}, nil
    45	}
    46	
    47	func (fd *netFD) init() error {
    48		if err := fd.pd.init(fd); err != nil {
    49			return err
    50		}
    51		return nil
    52	}
    53	
    54	func (fd *netFD) setAddr(laddr, raddr Addr) {
    55		fd.laddr = laddr
    56		fd.raddr = raddr
    57		runtime.SetFinalizer(fd, (*netFD).Close)
    58	}
    59	
    60	func (fd *netFD) name() string {
    61		var ls, rs string
    62		if fd.laddr != nil {
    63			ls = fd.laddr.String()
    64		}
    65		if fd.raddr != nil {
    66			rs = fd.raddr.String()
    67		}
    68		return fd.net + ":" + ls + "->" + rs
    69	}
    70	
    71	func (fd *netFD) connect(ctx context.Context, la, ra syscall.Sockaddr) (ret error) {
    72		// Do not need to call fd.writeLock here,
    73		// because fd is not yet accessible to user,
    74		// so no concurrent operations are possible.
    75		switch err := connectFunc(fd.sysfd, ra); err {
    76		case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
    77		case nil, syscall.EISCONN:
    78			select {
    79			case <-ctx.Done():
    80				return mapErr(ctx.Err())
    81			default:
    82			}
    83			if err := fd.init(); err != nil {
    84				return err
    85			}
    86			return nil
    87		case syscall.EINVAL:
    88			// On Solaris we can see EINVAL if the socket has
    89			// already been accepted and closed by the server.
    90			// Treat this as a successful connection--writes to
    91			// the socket will see EOF.  For details and a test
    92			// case in C see https://golang.org/issue/6828.
    93			if runtime.GOOS == "solaris" {
    94				return nil
    95			}
    96			fallthrough
    97		default:
    98			return os.NewSyscallError("connect", err)
    99		}
   100		if err := fd.init(); err != nil {
   101			return err
   102		}
   103		if deadline, _ := ctx.Deadline(); !deadline.IsZero() {
   104			fd.setWriteDeadline(deadline)
   105			defer fd.setWriteDeadline(noDeadline)
   106		}
   107	
   108		// Start the "interrupter" goroutine, if this context might be canceled.
   109		// (The background context cannot)
   110		//
   111		// The interrupter goroutine waits for the context to be done and
   112		// interrupts the dial (by altering the fd's write deadline, which
   113		// wakes up waitWrite).
   114		if ctx != context.Background() {
   115			// Wait for the interrupter goroutine to exit before returning
   116			// from connect.
   117			done := make(chan struct{})
   118			interruptRes := make(chan error)
   119			defer func() {
   120				close(done)
   121				if ctxErr := <-interruptRes; ctxErr != nil && ret == nil {
   122					// The interrupter goroutine called setWriteDeadline,
   123					// but the connect code below had returned from
   124					// waitWrite already and did a successful connect (ret
   125					// == nil). Because we've now poisoned the connection
   126					// by making it unwritable, don't return a successful
   127					// dial. This was issue 16523.
   128					ret = ctxErr
   129					fd.Close() // prevent a leak
   130				}
   131			}()
   132			go func() {
   133				select {
   134				case <-ctx.Done():
   135					// Force the runtime's poller to immediately give up
   136					// waiting for writability, unblocking waitWrite
   137					// below.
   138					fd.setWriteDeadline(aLongTimeAgo)
   139					testHookCanceledDial()
   140					interruptRes <- ctx.Err()
   141				case <-done:
   142					interruptRes <- nil
   143				}
   144			}()
   145		}
   146	
   147		for {
   148			// Performing multiple connect system calls on a
   149			// non-blocking socket under Unix variants does not
   150			// necessarily result in earlier errors being
   151			// returned. Instead, once runtime-integrated network
   152			// poller tells us that the socket is ready, get the
   153			// SO_ERROR socket option to see if the connection
   154			// succeeded or failed. See issue 7474 for further
   155			// details.
   156			if err := fd.pd.waitWrite(); err != nil {
   157				select {
   158				case <-ctx.Done():
   159					return mapErr(ctx.Err())
   160				default:
   161				}
   162				return err
   163			}
   164			nerr, err := getsockoptIntFunc(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
   165			if err != nil {
   166				return os.NewSyscallError("getsockopt", err)
   167			}
   168			switch err := syscall.Errno(nerr); err {
   169			case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
   170			case syscall.Errno(0), syscall.EISCONN:
   171				if runtime.GOOS != "darwin" {
   172					return nil
   173				}
   174				// See golang.org/issue/14548.
   175				// On Darwin, multiple connect system calls on
   176				// a non-blocking socket never harm SO_ERROR.
   177				switch err := connectFunc(fd.sysfd, ra); err {
   178				case nil, syscall.EISCONN:
   179					return nil
   180				}
   181			default:
   182				return os.NewSyscallError("getsockopt", err)
   183			}
   184		}
   185	}
   186	
   187	func (fd *netFD) destroy() {
   188		// Poller may want to unregister fd in readiness notification mechanism,
   189		// so this must be executed before closeFunc.
   190		fd.pd.close()
   191		closeFunc(fd.sysfd)
   192		fd.sysfd = -1
   193		runtime.SetFinalizer(fd, nil)
   194	}
   195	
   196	func (fd *netFD) Close() error {
   197		if !fd.fdmu.increfAndClose() {
   198			return errClosing
   199		}
   200		// Unblock any I/O.  Once it all unblocks and returns,
   201		// so that it cannot be referring to fd.sysfd anymore,
   202		// the final decref will close fd.sysfd. This should happen
   203		// fairly quickly, since all the I/O is non-blocking, and any
   204		// attempts to block in the pollDesc will return errClosing.
   205		fd.pd.evict()
   206		fd.decref()
   207		return nil
   208	}
   209	
   210	func (fd *netFD) shutdown(how int) error {
   211		if err := fd.incref(); err != nil {
   212			return err
   213		}
   214		defer fd.decref()
   215		return os.NewSyscallError("shutdown", syscall.Shutdown(fd.sysfd, how))
   216	}
   217	
   218	func (fd *netFD) closeRead() error {
   219		return fd.shutdown(syscall.SHUT_RD)
   220	}
   221	
   222	func (fd *netFD) closeWrite() error {
   223		return fd.shutdown(syscall.SHUT_WR)
   224	}
   225	
   226	func (fd *netFD) Read(p []byte) (n int, err error) {
   227		if err := fd.readLock(); err != nil {
   228			return 0, err
   229		}
   230		defer fd.readUnlock()
   231		if len(p) == 0 {
   232			// If the caller wanted a zero byte read, return immediately
   233			// without trying. (But after acquiring the readLock.) Otherwise
   234			// syscall.Read returns 0, nil and eofError turns that into
   235			// io.EOF.
   236			// TODO(bradfitz): make it wait for readability? (Issue 15735)
   237			return 0, nil
   238		}
   239		if err := fd.pd.prepareRead(); err != nil {
   240			return 0, err
   241		}
   242		if fd.isStream && len(p) > 1<<30 {
   243			p = p[:1<<30]
   244		}
   245		for {
   246			n, err = syscall.Read(fd.sysfd, p)
   247			if err != nil {
   248				n = 0
   249				if err == syscall.EAGAIN {
   250					if err = fd.pd.waitRead(); err == nil {
   251						continue
   252					}
   253				}
   254			}
   255			err = fd.eofError(n, err)
   256			break
   257		}
   258		if _, ok := err.(syscall.Errno); ok {
   259			err = os.NewSyscallError("read", err)
   260		}
   261		return
   262	}
   263	
   264	func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
   265		if err := fd.readLock(); err != nil {
   266			return 0, nil, err
   267		}
   268		defer fd.readUnlock()
   269		if err := fd.pd.prepareRead(); err != nil {
   270			return 0, nil, err
   271		}
   272		for {
   273			n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0)
   274			if err != nil {
   275				n = 0
   276				if err == syscall.EAGAIN {
   277					if err = fd.pd.waitRead(); err == nil {
   278						continue
   279					}
   280				}
   281			}
   282			err = fd.eofError(n, err)
   283			break
   284		}
   285		if _, ok := err.(syscall.Errno); ok {
   286			err = os.NewSyscallError("recvfrom", err)
   287		}
   288		return
   289	}
   290	
   291	func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
   292		if err := fd.readLock(); err != nil {
   293			return 0, 0, 0, nil, err
   294		}
   295		defer fd.readUnlock()
   296		if err := fd.pd.prepareRead(); err != nil {
   297			return 0, 0, 0, nil, err
   298		}
   299		for {
   300			n, oobn, flags, sa, err = syscall.Recvmsg(fd.sysfd, p, oob, 0)
   301			if err != nil {
   302				// TODO(dfc) should n and oobn be set to 0
   303				if err == syscall.EAGAIN {
   304					if err = fd.pd.waitRead(); err == nil {
   305						continue
   306					}
   307				}
   308			}
   309			err = fd.eofError(n, err)
   310			break
   311		}
   312		if _, ok := err.(syscall.Errno); ok {
   313			err = os.NewSyscallError("recvmsg", err)
   314		}
   315		return
   316	}
   317	
   318	func (fd *netFD) Write(p []byte) (nn int, err error) {
   319		if err := fd.writeLock(); err != nil {
   320			return 0, err
   321		}
   322		defer fd.writeUnlock()
   323		if err := fd.pd.prepareWrite(); err != nil {
   324			return 0, err
   325		}
   326		for {
   327			var n int
   328			max := len(p)
   329			if fd.isStream && max-nn > 1<<30 {
   330				max = nn + 1<<30
   331			}
   332			n, err = syscall.Write(fd.sysfd, p[nn:max])
   333			if n > 0 {
   334				nn += n
   335			}
   336			if nn == len(p) {
   337				break
   338			}
   339			if err == syscall.EAGAIN {
   340				if err = fd.pd.waitWrite(); err == nil {
   341					continue
   342				}
   343			}
   344			if err != nil {
   345				break
   346			}
   347			if n == 0 {
   348				err = io.ErrUnexpectedEOF
   349				break
   350			}
   351		}
   352		if _, ok := err.(syscall.Errno); ok {
   353			err = os.NewSyscallError("write", err)
   354		}
   355		return nn, err
   356	}
   357	
   358	func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
   359		if err := fd.writeLock(); err != nil {
   360			return 0, err
   361		}
   362		defer fd.writeUnlock()
   363		if err := fd.pd.prepareWrite(); err != nil {
   364			return 0, err
   365		}
   366		for {
   367			err = syscall.Sendto(fd.sysfd, p, 0, sa)
   368			if err == syscall.EAGAIN {
   369				if err = fd.pd.waitWrite(); err == nil {
   370					continue
   371				}
   372			}
   373			break
   374		}
   375		if err == nil {
   376			n = len(p)
   377		}
   378		if _, ok := err.(syscall.Errno); ok {
   379			err = os.NewSyscallError("sendto", err)
   380		}
   381		return
   382	}
   383	
   384	func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
   385		if err := fd.writeLock(); err != nil {
   386			return 0, 0, err
   387		}
   388		defer fd.writeUnlock()
   389		if err := fd.pd.prepareWrite(); err != nil {
   390			return 0, 0, err
   391		}
   392		for {
   393			n, err = syscall.SendmsgN(fd.sysfd, p, oob, sa, 0)
   394			if err == syscall.EAGAIN {
   395				if err = fd.pd.waitWrite(); err == nil {
   396					continue
   397				}
   398			}
   399			break
   400		}
   401		if err == nil {
   402			oobn = len(oob)
   403		}
   404		if _, ok := err.(syscall.Errno); ok {
   405			err = os.NewSyscallError("sendmsg", err)
   406		}
   407		return
   408	}
   409	
   410	func (fd *netFD) accept() (netfd *netFD, err error) {
   411		if err := fd.readLock(); err != nil {
   412			return nil, err
   413		}
   414		defer fd.readUnlock()
   415	
   416		var s int
   417		var rsa syscall.Sockaddr
   418		if err = fd.pd.prepareRead(); err != nil {
   419			return nil, err
   420		}
   421		for {
   422			s, rsa, err = accept(fd.sysfd)
   423			if err != nil {
   424				nerr, ok := err.(*os.SyscallError)
   425				if !ok {
   426					return nil, err
   427				}
   428				switch nerr.Err {
   429				case syscall.EAGAIN:
   430					if err = fd.pd.waitRead(); err == nil {
   431						continue
   432					}
   433				case syscall.ECONNABORTED:
   434					// This means that a socket on the
   435					// listen queue was closed before we
   436					// Accept()ed it; it's a silly error,
   437					// so try again.
   438					continue
   439				}
   440				return nil, err
   441			}
   442			break
   443		}
   444	
   445		if netfd, err = newFD(s, fd.family, fd.sotype, fd.net); err != nil {
   446			closeFunc(s)
   447			return nil, err
   448		}
   449		if err = netfd.init(); err != nil {
   450			fd.Close()
   451			return nil, err
   452		}
   453		lsa, _ := syscall.Getsockname(netfd.sysfd)
   454		netfd.setAddr(netfd.addrFunc()(lsa), netfd.addrFunc()(rsa))
   455		return netfd, nil
   456	}
   457	
   458	// tryDupCloexec indicates whether F_DUPFD_CLOEXEC should be used.
   459	// If the kernel doesn't support it, this is set to 0.
   460	var tryDupCloexec = int32(1)
   461	
   462	func dupCloseOnExec(fd int) (newfd int, err error) {
   463		if atomic.LoadInt32(&tryDupCloexec) == 1 {
   464			r0, _, e1 := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_DUPFD_CLOEXEC, 0)
   465			if runtime.GOOS == "darwin" && e1 == syscall.EBADF {
   466				// On OS X 10.6 and below (but we only support
   467				// >= 10.6), F_DUPFD_CLOEXEC is unsupported
   468				// and fcntl there falls back (undocumented)
   469				// to doing an ioctl instead, returning EBADF
   470				// in this case because fd is not of the
   471				// expected device fd type. Treat it as
   472				// EINVAL instead, so we fall back to the
   473				// normal dup path.
   474				// TODO: only do this on 10.6 if we can detect 10.6
   475				// cheaply.
   476				e1 = syscall.EINVAL
   477			}
   478			switch e1 {
   479			case 0:
   480				return int(r0), nil
   481			case syscall.EINVAL:
   482				// Old kernel. Fall back to the portable way
   483				// from now on.
   484				atomic.StoreInt32(&tryDupCloexec, 0)
   485			default:
   486				return -1, os.NewSyscallError("fcntl", e1)
   487			}
   488		}
   489		return dupCloseOnExecOld(fd)
   490	}
   491	
   492	// dupCloseOnExecUnixOld is the traditional way to dup an fd and
   493	// set its O_CLOEXEC bit, using two system calls.
   494	func dupCloseOnExecOld(fd int) (newfd int, err error) {
   495		syscall.ForkLock.RLock()
   496		defer syscall.ForkLock.RUnlock()
   497		newfd, err = syscall.Dup(fd)
   498		if err != nil {
   499			return -1, os.NewSyscallError("dup", err)
   500		}
   501		syscall.CloseOnExec(newfd)
   502		return
   503	}
   504	
   505	func (fd *netFD) dup() (f *os.File, err error) {
   506		ns, err := dupCloseOnExec(fd.sysfd)
   507		if err != nil {
   508			return nil, err
   509		}
   510	
   511		// We want blocking mode for the new fd, hence the double negative.
   512		// This also puts the old fd into blocking mode, meaning that
   513		// I/O will block the thread instead of letting us use the epoll server.
   514		// Everything will still work, just with more threads.
   515		if err = syscall.SetNonblock(ns, false); err != nil {
   516			return nil, os.NewSyscallError("setnonblock", err)
   517		}
   518	
   519		return os.NewFile(uintptr(ns), fd.name()), nil
   520	}
   521	

View as plain text