1 // 2 // local/detail/impl/endpoint.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // Derived from a public domain implementation written by Daniel Casimiro. 7 // 8 // Distributed under the Boost Software License, Version 1.0. (See accompanying 9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 10 // 11 12 #ifndef ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP 13 #define ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP 14 15 16 #include "asio/detail/config.hpp" 17 18 19 #include <cstring> 20 #include "asio/detail/socket_ops.hpp" 21 #include "asio/detail/throw_error.hpp" 22 #include "asio/error.hpp" 23 #include "asio/local/detail/endpoint.hpp" 24 25 #include "asio/detail/push_options.hpp" 26 27 namespace asio { 28 namespace local { 29 namespace detail { 30 31 endpoint::endpoint() 32 { 33 init("", 0); 34 } 35 36 endpoint::endpoint(const char* path_name) 37 { 38 using namespace std; // For strlen. 39 init(path_name, strlen(path_name)); 40 } 41 42 endpoint::endpoint(const std::string& path_name) 43 { 44 init(path_name.data(), path_name.length()); 45 } 46 47 void endpoint::resize(std::size_t new_size) 48 { 49 if (new_size > sizeof(asio::detail::sockaddr_un_type)) 50 { 51 asio::error_code ec(asio::error::invalid_argument); 52 asio::detail::throw_error(ec); 53 } 54 else if (new_size == 0) 55 { 56 path_length_ = 0; 57 } 58 else 59 { 60 path_length_ = new_size 61 - offsetof(asio::detail::sockaddr_un_type, sun_path); 62 63 // The path returned by the operating system may be NUL-terminated. 64 if (path_length_ > 0 && data_.local.sun_path[path_length_ - 1] == 0) 65 --path_length_; 66 } 67 } 68 69 std::string endpoint::path() const 70 { 71 return std::string(data_.local.sun_path, path_length_); 72 } 73 74 void endpoint::path(const char* p) 75 { 76 using namespace std; // For strlen. 77 init(p, strlen(p)); 78 } 79 80 void endpoint::path(const std::string& p) 81 { 82 init(p.data(), p.length()); 83 } 84 85 bool operator==(const endpoint& e1, const endpoint& e2) 86 { 87 return e1.path() == e2.path(); 88 } 89 90 bool operator<(const endpoint& e1, const endpoint& e2) 91 { 92 return e1.path() < e2.path(); 93 } 94 95 void endpoint::init(const char* path_name, std::size_t path_length) 96 { 97 if (path_length > sizeof(data_.local.sun_path) - 1) 98 { 99 // The buffer is not large enough to store this address. 100 asio::error_code ec(asio::error::name_too_long); 101 asio::detail::throw_error(ec); 102 } 103 104 using namespace std; // For memcpy. 105 data_.local = asio::detail::sockaddr_un_type(); 106 data_.local.sun_family = AF_UNIX; 107 memcpy(data_.local.sun_path, path_name, path_length); 108 path_length_ = path_length; 109 110 // NUL-terminate normal path names. Names that start with a NUL are in the 111 // UNIX domain protocol's "abstract namespace" and are not NUL-terminated. 112 if (path_length > 0 && data_.local.sun_path[0] == 0) 113 data_.local.sun_path[path_length] = 0; 114 } 115 116 } // namespace detail 117 } // namespace local 118 } // namespace asio 119 120 #include "asio/detail/pop_options.hpp" 121 122 123 #endif // ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP 124