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 27namespace asio { 28namespace local { 29namespace detail { 30 31endpoint::endpoint() 32{ 33 init("", 0); 34} 35 36endpoint::endpoint(const char* path_name) 37{ 38 using namespace std; // For strlen. 39 init(path_name, strlen(path_name)); 40} 41 42endpoint::endpoint(const std::string& path_name) 43{ 44 init(path_name.data(), path_name.length()); 45} 46 47void 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 69std::string endpoint::path() const 70{ 71 return std::string(data_.local.sun_path, path_length_); 72} 73 74void endpoint::path(const char* p) 75{ 76 using namespace std; // For strlen. 77 init(p, strlen(p)); 78} 79 80void endpoint::path(const std::string& p) 81{ 82 init(p.data(), p.length()); 83} 84 85bool operator==(const endpoint& e1, const endpoint& e2) 86{ 87 return e1.path() == e2.path(); 88} 89 90bool operator<(const endpoint& e1, const endpoint& e2) 91{ 92 return e1.path() < e2.path(); 93} 94 95void 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