| 124 | } |
| 125 | |
| 126 | Status Sockaddr::ParseUnixDomainPath(const string& s) { |
| 127 | constexpr auto kMaxPathSize = SIZEOF_MEMBER(struct sockaddr_un, sun_path); |
| 128 | if (s[0] == '@') { |
| 129 | // Specify a path in the abstract namespace. |
| 130 | if (s.size() > kMaxPathSize) { |
| 131 | return Status::InvalidArgument(Substitute( |
| 132 | "UNIX domain socket path exceeds maximum length $0", kMaxPathSize)); |
| 133 | } |
| 134 | set_length(offsetof(struct sockaddr_un, sun_path) + s.size()); |
| 135 | storage_.un.sun_family = AF_UNIX; |
| 136 | memcpy(storage_.un.sun_path, s.data(), s.size()); |
| 137 | storage_.un.sun_path[0] = '\0'; |
| 138 | } else { |
| 139 | // Path names must be null-terminated. The null-terminated length |
| 140 | // may not match the length s.size(). |
| 141 | int c_len = strlen(s.c_str()); |
| 142 | if (c_len != s.size()) { |
| 143 | return Status::InvalidArgument("UNIX domain socket path must not contain null bytes"); |
| 144 | } |
| 145 | // Per unix(7) the length of the path name, including the terminating null |
| 146 | // byte, should not exceed the size of sun_path. |
| 147 | if (c_len + 1 > kMaxPathSize) { |
| 148 | return Status::InvalidArgument(Substitute( |
| 149 | "UNIX domain socket path exceeds maximum length $0", kMaxPathSize)); |
| 150 | } |
| 151 | // unix(7) says the addrlen can be specified as the full length of the |
| 152 | // structure. |
| 153 | set_length(sizeof(struct sockaddr_un)); |
| 154 | storage_.un.sun_family = AF_UNIX; |
| 155 | memcpy(storage_.un.sun_path, s.c_str(), c_len + 1); |
| 156 | } |
| 157 | return Status::OK(); |
| 158 | } |
| 159 | |
| 160 | string Sockaddr::UnixDomainPath() const { |
| 161 | CHECK_EQ(family(), AF_UNIX); |