func recvFd(socket *net.UnixConn) (*os.File, error) {
	const MaxNameLen = 4096
	var oobSpace = unix.CmsgSpace(4)
	name := make([]byte, MaxNameLen)
	oob := make([]byte, oobSpace)
	n, oobn, _, _, err := socket.ReadMsgUnix(name, oob)
	if err != nil {
		return nil, err
	}
	if n >= MaxNameLen || oobn != oobSpace {
		return nil, fmt.Errorf("recvfd: incorrect number of bytes read (n=%d oobn=%d)", n, oobn)
	}
	name = name[:n]
	oob = oob[:oobn]
	scms, err := unix.ParseSocketControlMessage(oob)
	if err != nil {
		return nil, err
	}
	if len(scms) != 1 {
		return nil, fmt.Errorf("recvfd: number of SCMs is not 1: %d", len(scms))
	}
	scm := scms[0]
	fds, err := unix.ParseUnixRights(&scm)
	if err != nil {
		return nil, err
	}
	if len(fds) != 1 {
		return nil, fmt.Errorf("recvfd: number of fds is not 1: %d", len(fds))
	}
	fd := uintptr(fds[0])
	return os.NewFile(fd, string(name)), nil
}
recvFd waits for a file descriptor to be sent over the given AF_UNIX
socket. The file name of the remote file descriptor will be recreated
locally (it is sent as non-auxiliary data in the same payload).
package runc
import (
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"path/filepath"
	"github.com/containerd/console"
	"golang.org/x/sys/unix"
)
func NewConsoleSocket(path string) (*Socket, error) {
	abs, err := filepath.Abs(path)
	if err != nil {
		return nil, err
	}
	addr, err := net.ResolveUnixAddr("unix", abs)
	if err != nil {
		return nil, err
	}
	l, err := net.ListenUnix("unix", addr)
	if err != nil {
		return nil, err
	}
	return &Socket{
		l: l,
	}, nil
}
func NewTempConsoleSocket() (*Socket, error) {
	runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
	dir, err := ioutil.TempDir(runtimeDir, "pty")
	if err != nil {
		return nil, err
	}
	abs, err := filepath.Abs(filepath.Join(dir, "pty.sock"))
	if err != nil {
		return nil, err
	}
	addr, err := net.ResolveUnixAddr("unix", abs)
	if err != nil {
		return nil, err
	}
	l, err := net.ListenUnix("unix", addr)
	if err != nil {
		return nil, err
	}
	if runtimeDir != "" {
		if err := os.Chmod(abs, 0755|os.ModeSticky); err != nil {
			return nil, err
		}
	}
	return &Socket{
		l:     l,
		rmdir: true,
	}, nil
}
type Socket struct {
	rmdir bool
	l     *net.UnixListener
}
func (c *Socket) Path() string {
	return c.l.Addr().String()
}