If one thread does a connect to localhost on a non-blocking socket such that the connect fails with EINPROGRESS, and then another thread accepts the connection and closes the accepted socket, and then the first thread does the connect again, that connect should succeed and return a socket whose other end is closed. For some reason, on Solaris, the second connect fails with an error of EINVAL, a possibility that is not documented on the connect man page. This case arises in some of the libgo testsuite. This patch works around the problem by testing for this possibility on Solaris. The same patch has been applied to the master Go repository. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu, which I admit proves little for a Solaris-specific patch. I also tested the specific patch on i386-pc-solaris2.11, where it fixes a testsuite failure. Committed to mainline and 4.8 branch.
Ian
diff -r 0d4f83bb938b src/pkg/net/fd_unix.go --- a/src/pkg/net/fd_unix.go Sat Dec 28 20:33:05 2013 +1100 +++ b/src/pkg/net/fd_unix.go Sat Dec 28 09:37:28 2013 -0800 @@ -80,6 +80,16 @@ if err == nil || err == syscall.EISCONN { break } + + // On Solaris 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 http://golang.org/issue/6828. + if runtime.GOOS == "solaris" && err == syscall.EINVAL { + break + } + if err != syscall.EINPROGRESS && err != syscall.EALREADY && err != syscall.EINTR { return err }