Copyright 2009 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+build aix darwin dragonfly freebsd linux netbsd openbsd solaris

package net

import (
	
	
	
	
	
)

const (
	readSyscallName     = "read"
	readFromSyscallName = "recvfrom"
	readMsgSyscallName  = "recvmsg"
	writeSyscallName    = "write"
	writeToSyscallName  = "sendto"
	writeMsgSyscallName = "sendmsg"
)

func (, ,  int,  string) (*netFD, error) {
	 := &netFD{
		pfd: poll.FD{
			Sysfd:         ,
			IsStream:       == syscall.SOCK_STREAM,
			ZeroReadIsEOF:  != syscall.SOCK_DGRAM &&  != syscall.SOCK_RAW,
		},
		family: ,
		sotype: ,
		net:    ,
	}
	return , nil
}

func ( *netFD) () error {
	return .pfd.Init(.net, true)
}

func ( *netFD) () string {
	var ,  string
	if .laddr != nil {
		 = .laddr.String()
	}
	if .raddr != nil {
		 = .raddr.String()
	}
	return .net + ":" +  + "->" + 
}

Do not need to call fd.writeLock here, because fd is not yet accessible to user, so no concurrent operations are possible.
	switch  := connectFunc(.pfd.Sysfd, );  {
	case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
	case nil, syscall.EISCONN:
		select {
		case <-.Done():
			return nil, mapErr(.Err())
		default:
		}
		if  := .pfd.Init(.net, true);  != nil {
			return nil, 
		}
		runtime.KeepAlive()
		return nil, nil
On Solaris and illumos we can see EINVAL if the socket has already been accepted and closed by the server. Treat this as a successful connection--writes to the socket will see EOF. For details and a test case in C see https://golang.org/issue/6828.
		if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" {
			return nil, nil
		}
		fallthrough
	default:
		return nil, os.NewSyscallError("connect", )
	}
	if  := .pfd.Init(.net, true);  != nil {
		return nil, 
	}
	if ,  := .Deadline();  {
		.pfd.SetWriteDeadline()
		defer .pfd.SetWriteDeadline(noDeadline)
	}
Start the "interrupter" goroutine, if this context might be canceled. (The background context cannot) The interrupter goroutine waits for the context to be done and interrupts the dial (by altering the fd's write deadline, which wakes up waitWrite).
Wait for the interrupter goroutine to exit before returning from connect.
		 := make(chan struct{})
		 := make(chan error)
		defer func() {
			close()
The interrupter goroutine called SetWriteDeadline, but the connect code below had returned from waitWrite already and did a successful connect (ret == nil). Because we've now poisoned the connection by making it unwritable, don't return a successful dial. This was issue 16523.
				 = mapErr()
				.Close() // prevent a leak
			}
		}()
		go func() {
			select {
Force the runtime's poller to immediately give up waiting for writability, unblocking waitWrite below.
				.pfd.SetWriteDeadline(aLongTimeAgo)
				testHookCanceledDial()
				 <- .Err()
			case <-:
				 <- nil
			}
		}()
	}

Performing multiple connect system calls on a non-blocking socket under Unix variants does not necessarily result in earlier errors being returned. Instead, once runtime-integrated network poller tells us that the socket is ready, get the SO_ERROR socket option to see if the connection succeeded or failed. See issue 7474 for further details.
		if  := .pfd.WaitWrite();  != nil {
			select {
			case <-.Done():
				return nil, mapErr(.Err())
			default:
			}
			return nil, 
		}
		,  := getsockoptIntFunc(.pfd.Sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
		if  != nil {
			return nil, os.NewSyscallError("getsockopt", )
		}
		switch  := syscall.Errno();  {
		case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
		case syscall.EISCONN:
			return nil, nil
The runtime poller can wake us up spuriously; see issues 14548 and 19289. Check that we are really connected; if not, wait again.
			if ,  := syscall.Getpeername(.pfd.Sysfd);  == nil {
				return , nil
			}
		default:
			return nil, os.NewSyscallError("connect", )
		}
		runtime.KeepAlive()
	}
}

func ( *netFD) () ( *netFD,  error) {
	, , ,  := .pfd.Accept()
	if  != nil {
		if  != "" {
			 = wrapSyscallError(, )
		}
		return nil, 
	}

	if ,  = newFD(, .family, .sotype, .net);  != nil {
		poll.CloseFunc()
		return nil, 
	}
	if  = .init();  != nil {
		.Close()
		return nil, 
	}
	,  := syscall.Getsockname(.pfd.Sysfd)
	.setAddr(.addrFunc()(), .addrFunc()())
	return , nil
}

func ( *netFD) () ( *os.File,  error) {
	, ,  := .pfd.Dup()
	if  != nil {
		if  != "" {
			 = os.NewSyscallError(, )
		}
		return nil, 
	}

	return os.NewFile(uintptr(), .name()), nil