| 261 | } |
| 262 | |
| 263 | bool FileDescriptorInfo::GetSocketName(std::string* result) { |
| 264 | sockaddr_storage ss; |
| 265 | sockaddr* addr = reinterpret_cast<sockaddr*>(&ss); |
| 266 | socklen_t addr_len = sizeof(ss); |
| 267 | if (TEMP_FAILURE_RETRY(getsockname(fd, addr, &addr_len)) == -1) { |
| 268 | return false; |
| 269 | } |
| 270 | if (addr->sa_family != AF_UNIX) { |
| 271 | return false; |
| 272 | } |
| 273 | const sockaddr_un* unix_addr = reinterpret_cast<const sockaddr_un*>(&ss); |
| 274 | size_t path_len = addr_len - offsetof(struct sockaddr_un, sun_path); |
| 275 | // This is an unnamed local socket, we do not accept it. |
| 276 | if (path_len == 0) { |
| 277 | return false; |
| 278 | } |
| 279 | // This is a local socket with an abstract address. Remove the leading NUL byte and |
| 280 | // add a human-readable "ABSTRACT/" prefix. |
| 281 | if (unix_addr->sun_path[0] == '\0') { |
| 282 | *result = "ABSTRACT/"; |
| 283 | result->append(&unix_addr->sun_path[1], path_len - 1); |
| 284 | return true; |
| 285 | } |
| 286 | // If we're here, sun_path must refer to a null terminated filesystem |
| 287 | // pathname (man 7 unix). Remove the terminator before assigning it to an |
| 288 | // std::string. |
| 289 | if (unix_addr->sun_path[path_len - 1] == '\0') { |
| 290 | --path_len; |
| 291 | } |
| 292 | result->assign(unix_addr->sun_path, path_len); |
| 293 | return true; |
| 294 | } |
| 295 | |
| 296 | // TODO: Move the definitions here and eliminate the forward declarations. They |
| 297 | // temporarily help making code reviews easier. |