| package sockaddr |
| |
| import ( |
| "fmt" |
| "strings" |
| ) |
| |
| type UnixSock struct { |
| SockAddr |
| path string |
| } |
| type UnixSocks []*UnixSock |
| |
| // unixAttrMap is a map of the UnixSockAddr type-specific attributes. |
| var unixAttrMap map[AttrName]func(UnixSock) string |
| var unixAttrs []AttrName |
| |
| func init() { |
| unixAttrInit() |
| } |
| |
| // NewUnixSock creates an UnixSock from a string path. String can be in the |
| // form of either URI-based string (e.g. `file:///etc/passwd`), an absolute |
| // path (e.g. `/etc/passwd`), or a relative path (e.g. `./foo`). |
| func NewUnixSock(s string) (ret UnixSock, err error) { |
| ret.path = s |
| return ret, nil |
| } |
| |
| // CmpAddress follows the Cmp() standard protocol and returns: |
| // |
| // - -1 If the receiver should sort first because its name lexically sorts before arg |
| // - 0 if the SockAddr arg is not a UnixSock, or is a UnixSock with the same path. |
| // - 1 If the argument should sort first. |
| func (us UnixSock) CmpAddress(sa SockAddr) int { |
| usb, ok := sa.(UnixSock) |
| if !ok { |
| return sortDeferDecision |
| } |
| |
| return strings.Compare(us.Path(), usb.Path()) |
| } |
| |
| // DialPacketArgs returns the arguments required to be passed to net.DialUnix() |
| // with the `unixgram` network type. |
| func (us UnixSock) DialPacketArgs() (network, dialArgs string) { |
| return "unixgram", us.path |
| } |
| |
| // DialStreamArgs returns the arguments required to be passed to net.DialUnix() |
| // with the `unix` network type. |
| func (us UnixSock) DialStreamArgs() (network, dialArgs string) { |
| return "unix", us.path |
| } |
| |
| // Equal returns true if a SockAddr is equal to the receiving UnixSock. |
| func (us UnixSock) Equal(sa SockAddr) bool { |
| usb, ok := sa.(UnixSock) |
| if !ok { |
| return false |
| } |
| |
| if us.Path() != usb.Path() { |
| return false |
| } |
| |
| return true |
| } |
| |
| // ListenPacketArgs returns the arguments required to be passed to |
| // net.ListenUnixgram() with the `unixgram` network type. |
| func (us UnixSock) ListenPacketArgs() (network, dialArgs string) { |
| return "unixgram", us.path |
| } |
| |
| // ListenStreamArgs returns the arguments required to be passed to |
| // net.ListenUnix() with the `unix` network type. |
| func (us UnixSock) ListenStreamArgs() (network, dialArgs string) { |
| return "unix", us.path |
| } |
| |
| // MustUnixSock is a helper method that must return an UnixSock or panic on |
| // invalid input. |
| func MustUnixSock(addr string) UnixSock { |
| us, err := NewUnixSock(addr) |
| if err != nil { |
| panic(fmt.Sprintf("Unable to create a UnixSock from %+q: %v", addr, err)) |
| } |
| return us |
| } |
| |
| // Path returns the given path of the UnixSock |
| func (us UnixSock) Path() string { |
| return us.path |
| } |
| |
| // String returns the path of the UnixSock |
| func (us UnixSock) String() string { |
| return fmt.Sprintf("%+q", us.path) |
| } |
| |
| // Type is used as a type switch and returns TypeUnix |
| func (UnixSock) Type() SockAddrType { |
| return TypeUnix |
| } |
| |
| // UnixSockAttrs returns a list of attributes supported by the UnixSockAddr type |
| func UnixSockAttrs() []AttrName { |
| return unixAttrs |
| } |
| |
| // UnixSockAttr returns a string representation of an attribute for the given |
| // UnixSock. |
| func UnixSockAttr(us UnixSock, attrName AttrName) string { |
| fn, found := unixAttrMap[attrName] |
| if !found { |
| return "" |
| } |
| |
| return fn(us) |
| } |
| |
| // unixAttrInit is called once at init() |
| func unixAttrInit() { |
| // Sorted for human readability |
| unixAttrs = []AttrName{ |
| "path", |
| } |
| |
| unixAttrMap = map[AttrName]func(us UnixSock) string{ |
| "path": func(us UnixSock) string { |
| return us.Path() |
| }, |
| } |
| } |