Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: FileConn() and Dial() only return public net.Conn implementations #27391

dfinkel opened this issue Aug 30, 2018 · 3 comments


Copy link

@dfinkel dfinkel commented Aug 30, 2018

In Go 1.11 and 1.10, the documentation does not say anything about which implementations of net.Conn are actually returned by net.Dial() (and friends) and net.FileConn().

The current implementations of net.Dial() and net.FileConn() only return public implementations of net.Conn (or an error). Taking advantage of this by type-asserting to the actual implementation returned by these functions/methods is extremely useful. As such, it would be nice to have this behavior documented so users can rely on it.

I'll send out a CL to extend the documentation and a test or two shortly.


This comment has been minimized.

Copy link

@gopherbot gopherbot commented Aug 30, 2018

Change mentions this issue: net: extend documentation for net.FileConn()


This comment has been minimized.

Copy link

@ianlancetaylor ianlancetaylor commented Aug 31, 2018

For what kind of code does this matter?


This comment has been minimized.

Copy link
Contributor Author

@dfinkel dfinkel commented Aug 31, 2018

This is particularly with unix sockets where one might want access to the non-generic Conn methods. (e.g. (*UnixConn).SetWriteBuffer()1 which isn't in the Conn interface)

My specific use-case is that I'm constructing a unix socket with syscall.SocketPair()2 to communicate data with a subprocess that's being spawned with os.Exec, and it's much nicer if my function for creating the socket can return the correct net.Conn implementation.

In this case, I'd like the documentation reflect that this will never return the "failed to type-assert back to a UnixConn" error below (with some error-checking elided for simplicity):

func SocketPair() (*os.File, *net.UnixConn, error)
	fds, _ := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)

	// Convert these into os.files.
	var files [2]*os.File
	for i, fd := range fds {
		files[i] = os.NewFile(uintptr(fd), fmt.Sprintf("anonymous-socket-%d", i))

	conn, _ := net.FileConn(files[1])

	unixConn, ok := conn.(*net.UnixConn)
	if !ok {
		for _, file := range files {
		return nil, nil, fmt.Errorf("failed to type-assert back to a UnixConn. conn type: %T", conn)

	// Since FileConn dup'd the files[1] FD, we need to close that FD.
	// Since we never wrote to this FD closing should always succeed.
	if err := files[1].Close(); err != nil {
		// We don't want to leak an FD for every process.
		log.Panicf("Failed to close a unix FD: %s", err)
	return files[0], unixConn, nil

The use-case for Dial() is less clear to me due to the presence of DialUnix(), DialTCP, etc, but it seems odd to document that the less-used FileConn won't use a random private type when Dial() doesn't document similar behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
4 participants
You can’t perform that action at this time.