package beam import ( "net" ) // Listen is a convenience interface for applications to create service endpoints // which can be easily used with existing networking code. // // Listen registers a new service endpoint on the beam connection `conn`, using the // service name `name`. It returns a listener which can be used in the usual // way. Calling Accept() on the listener will block until a new connection is available // on the service endpoint. The endpoint is then returned as a regular net.Conn and // can be used as a regular network connection. // // Note that if the underlying file descriptor received in attachment is nil or does // not point to a connection, that message will be skipped. // func Listen(conn *net.UnixConn, name string) (net.Listener, error) { endpoint, err := SendPipe(conn, []byte(name)) if err != nil { return nil, err } return &listener{ name: name, endpoint: endpoint, }, nil } func Connect(ctx *net.UnixConn, name string) (net.Conn, error) { l, err := Listen(ctx, name) if err != nil { return nil, err } conn, err := l.Accept() if err != nil { return nil, err } return conn, nil } type listener struct { name string endpoint *net.UnixConn } func (l *listener) Accept() (net.Conn, error) { for { _, f, err := Receive(l.endpoint) if err != nil { return nil, err } if f == nil { // Skip empty attachments continue } conn, err := net.FileConn(f) if err != nil { // Skip beam attachments which are not connections // (for example might be a regular file, directory etc) continue } return conn, nil } panic("impossibru!") return nil, nil } func (l *listener) Close() error { return l.endpoint.Close() } func (l *listener) Addr() net.Addr { return addr(l.name) } type addr string func (a addr) Network() string { return "beam" } func (a addr) String() string { return string(a) }