unixsock.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package sockaddr
  2. import (
  3. "fmt"
  4. "strings"
  5. )
  6. type UnixSock struct {
  7. SockAddr
  8. path string
  9. }
  10. type UnixSocks []*UnixSock
  11. // unixAttrMap is a map of the UnixSockAddr type-specific attributes.
  12. var unixAttrMap map[AttrName]func(UnixSock) string
  13. var unixAttrs []AttrName
  14. func init() {
  15. unixAttrInit()
  16. }
  17. // NewUnixSock creates an UnixSock from a string path. String can be in the
  18. // form of either URI-based string (e.g. `file:///etc/passwd`), an absolute
  19. // path (e.g. `/etc/passwd`), or a relative path (e.g. `./foo`).
  20. func NewUnixSock(s string) (ret UnixSock, err error) {
  21. ret.path = s
  22. return ret, nil
  23. }
  24. // CmpAddress follows the Cmp() standard protocol and returns:
  25. //
  26. // - -1 If the receiver should sort first because its name lexically sorts before arg
  27. // - 0 if the SockAddr arg is not a UnixSock, or is a UnixSock with the same path.
  28. // - 1 If the argument should sort first.
  29. func (us UnixSock) CmpAddress(sa SockAddr) int {
  30. usb, ok := sa.(UnixSock)
  31. if !ok {
  32. return sortDeferDecision
  33. }
  34. return strings.Compare(us.Path(), usb.Path())
  35. }
  36. // DialPacketArgs returns the arguments required to be passed to net.DialUnix()
  37. // with the `unixgram` network type.
  38. func (us UnixSock) DialPacketArgs() (network, dialArgs string) {
  39. return "unixgram", us.path
  40. }
  41. // DialStreamArgs returns the arguments required to be passed to net.DialUnix()
  42. // with the `unix` network type.
  43. func (us UnixSock) DialStreamArgs() (network, dialArgs string) {
  44. return "unix", us.path
  45. }
  46. // Equal returns true if a SockAddr is equal to the receiving UnixSock.
  47. func (us UnixSock) Equal(sa SockAddr) bool {
  48. usb, ok := sa.(UnixSock)
  49. if !ok {
  50. return false
  51. }
  52. if us.Path() != usb.Path() {
  53. return false
  54. }
  55. return true
  56. }
  57. // ListenPacketArgs returns the arguments required to be passed to
  58. // net.ListenUnixgram() with the `unixgram` network type.
  59. func (us UnixSock) ListenPacketArgs() (network, dialArgs string) {
  60. return "unixgram", us.path
  61. }
  62. // ListenStreamArgs returns the arguments required to be passed to
  63. // net.ListenUnix() with the `unix` network type.
  64. func (us UnixSock) ListenStreamArgs() (network, dialArgs string) {
  65. return "unix", us.path
  66. }
  67. // MustUnixSock is a helper method that must return an UnixSock or panic on
  68. // invalid input.
  69. func MustUnixSock(addr string) UnixSock {
  70. us, err := NewUnixSock(addr)
  71. if err != nil {
  72. panic(fmt.Sprintf("Unable to create a UnixSock from %+q: %v", addr, err))
  73. }
  74. return us
  75. }
  76. // Path returns the given path of the UnixSock
  77. func (us UnixSock) Path() string {
  78. return us.path
  79. }
  80. // String returns the path of the UnixSock
  81. func (us UnixSock) String() string {
  82. return fmt.Sprintf("%+q", us.path)
  83. }
  84. // Type is used as a type switch and returns TypeUnix
  85. func (UnixSock) Type() SockAddrType {
  86. return TypeUnix
  87. }
  88. // UnixSockAttrs returns a list of attributes supported by the UnixSockAddr type
  89. func UnixSockAttrs() []AttrName {
  90. return unixAttrs
  91. }
  92. // UnixSockAttr returns a string representation of an attribute for the given
  93. // UnixSock.
  94. func UnixSockAttr(us UnixSock, attrName AttrName) string {
  95. fn, found := unixAttrMap[attrName]
  96. if !found {
  97. return ""
  98. }
  99. return fn(us)
  100. }
  101. // unixAttrInit is called once at init()
  102. func unixAttrInit() {
  103. // Sorted for human readability
  104. unixAttrs = []AttrName{
  105. "path",
  106. }
  107. unixAttrMap = map[AttrName]func(us UnixSock) string{
  108. "path": func(us UnixSock) string {
  109. return us.Path()
  110. },
  111. }
  112. }