github.com/gdamore/mangos@v1.4.0/transport/ipc/ipc_unix.go (about) 1 // +build !windows,!nacl,!plan9 2 3 // Copyright 2018 The Mangos Authors 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use file except in compliance with the License. 7 // You may obtain a copy of the license at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 // Package ipc implements the IPC transport on top of UNIX domain sockets. 18 package ipc 19 20 import ( 21 "net" 22 23 "nanomsg.org/go-mangos" 24 ) 25 26 // options is used for shared GetOption/SetOption logic. 27 type options map[string]interface{} 28 29 // GetOption retrieves an option value. 30 func (o options) get(name string) (interface{}, error) { 31 if o == nil { 32 return nil, mangos.ErrBadOption 33 } 34 v, ok := o[name] 35 if !ok { 36 return nil, mangos.ErrBadOption 37 } 38 return v, nil 39 } 40 41 // SetOption sets an option. We have none, so just ErrBadOption. 42 func (o options) set(string, interface{}) error { 43 return mangos.ErrBadOption 44 } 45 46 type dialer struct { 47 addr *net.UnixAddr 48 sock mangos.Socket 49 opts options 50 } 51 52 // Dial implements the PipeDialer Dial method 53 func (d *dialer) Dial() (mangos.Pipe, error) { 54 55 conn, err := net.DialUnix("unix", nil, d.addr) 56 if err != nil { 57 return nil, err 58 } 59 return mangos.NewConnPipeIPC(conn, d.sock) 60 } 61 62 // SetOption implements a stub PipeDialer SetOption method. 63 func (d *dialer) SetOption(n string, v interface{}) error { 64 return d.opts.set(n, v) 65 } 66 67 // GetOption implements a stub PipeDialer GetOption method. 68 func (d *dialer) GetOption(n string) (interface{}, error) { 69 return d.opts.get(n) 70 } 71 72 type listener struct { 73 addr *net.UnixAddr 74 sock mangos.Socket 75 listener *net.UnixListener 76 opts options 77 } 78 79 // Listen implements the PipeListener Listen method. 80 func (l *listener) Listen() error { 81 listener, err := net.ListenUnix("unix", l.addr) 82 if err != nil { 83 return err 84 } 85 l.listener = listener 86 return nil 87 } 88 89 func (l *listener) Address() string { 90 return "ipc://" + l.addr.String() 91 } 92 93 // Accept implements the the PipeListener Accept method. 94 func (l *listener) Accept() (mangos.Pipe, error) { 95 96 conn, err := l.listener.AcceptUnix() 97 if err != nil { 98 return nil, err 99 } 100 return mangos.NewConnPipeIPC(conn, l.sock) 101 } 102 103 // Close implements the PipeListener Close method. 104 func (l *listener) Close() error { 105 l.listener.Close() 106 return nil 107 } 108 109 // SetOption implements a stub PipeListener SetOption method. 110 func (l *listener) SetOption(n string, v interface{}) error { 111 return l.opts.set(n, v) 112 } 113 114 // GetOption implements a stub PipeListener GetOption method. 115 func (l *listener) GetOption(n string) (interface{}, error) { 116 return l.opts.get(n) 117 } 118 119 type ipcTran struct{} 120 121 // Scheme implements the Transport Scheme method. 122 func (t *ipcTran) Scheme() string { 123 return "ipc" 124 } 125 126 // NewDialer implements the Transport NewDialer method. 127 func (t *ipcTran) NewDialer(addr string, sock mangos.Socket) (mangos.PipeDialer, error) { 128 var err error 129 130 if addr, err = mangos.StripScheme(t, addr); err != nil { 131 return nil, err 132 } 133 134 d := &dialer{sock: sock, opts: nil} 135 if d.addr, err = net.ResolveUnixAddr("unix", addr); err != nil { 136 return nil, err 137 } 138 return d, nil 139 } 140 141 // NewListener implements the Transport NewListener method. 142 func (t *ipcTran) NewListener(addr string, sock mangos.Socket) (mangos.PipeListener, error) { 143 var err error 144 l := &listener{sock: sock} 145 146 if addr, err = mangos.StripScheme(t, addr); err != nil { 147 return nil, err 148 } 149 150 if l.addr, err = net.ResolveUnixAddr("unix", addr); err != nil { 151 return nil, err 152 } 153 154 return l, nil 155 } 156 157 // NewTransport allocates a new IPC transport. 158 func NewTransport() mangos.Transport { 159 return &ipcTran{} 160 }