1    	//
2    	// local/detail/impl/endpoint.hpp
3    	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4    	//
5    	// Copyright (c) 2003-2018 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 BOOST_ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP
13   	#define BOOST_ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP
14   	
15   	#if defined(_MSC_VER) && (_MSC_VER >= 1200)
16   	# pragma once
17   	#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18   	
19   	#include <boost/asio/detail/config.hpp>
20   	
21   	#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
22   	
23   	#include <cstring>
24   	#include <boost/asio/detail/socket_ops.hpp>
25   	#include <boost/asio/detail/throw_error.hpp>
26   	#include <boost/asio/error.hpp>
27   	#include <boost/asio/local/detail/endpoint.hpp>
28   	
29   	#include <boost/asio/detail/push_options.hpp>
30   	
31   	namespace boost {
32   	namespace asio {
33   	namespace local {
34   	namespace detail {
35   	
36   	endpoint::endpoint()
37   	{
38   	  init("", 0);
39   	}
40   	
41   	endpoint::endpoint(const char* path_name)
42   	{
43   	  using namespace std; // For strlen.
44   	  init(path_name, strlen(path_name));
45   	}
46   	
47   	endpoint::endpoint(const std::string& path_name)
48   	{
49   	  init(path_name.data(), path_name.length());
50   	}
51   	
52   	void endpoint::resize(std::size_t new_size)
53   	{
54   	  if (new_size > sizeof(boost::asio::detail::sockaddr_un_type))
55   	  {
56   	    boost::system::error_code ec(boost::asio::error::invalid_argument);
57   	    boost::asio::detail::throw_error(ec);
58   	  }
59   	  else if (new_size == 0)
60   	  {
61   	    path_length_ = 0;
62   	  }
63   	  else
64   	  {
65   	    path_length_ = new_size
66   	      - offsetof(boost::asio::detail::sockaddr_un_type, sun_path);
67   	
68   	    // The path returned by the operating system may be NUL-terminated.
69   	    if (path_length_ > 0 && data_.local.sun_path[path_length_ - 1] == 0)
70   	      --path_length_;
71   	  }
72   	}
73   	
74   	std::string endpoint::path() const
75   	{
76   	  return std::string(data_.local.sun_path, path_length_);
77   	}
78   	
79   	void endpoint::path(const char* p)
80   	{
81   	  using namespace std; // For strlen.
82   	  init(p, strlen(p));
83   	}
84   	
85   	void endpoint::path(const std::string& p)
86   	{
87   	  init(p.data(), p.length());
88   	}
89   	
90   	bool operator==(const endpoint& e1, const endpoint& e2)
91   	{
92   	  return e1.path() == e2.path();
93   	}
94   	
95   	bool operator<(const endpoint& e1, const endpoint& e2)
96   	{
97   	  return e1.path() < e2.path();
98   	}
99   	
100  	void endpoint::init(const char* path_name, std::size_t path_length)
101  	{
(1) Event cond_true: Condition "path_length > 107UL /* sizeof (this->data_.local.sun_path) - 1 */", taking true branch.
(2) Event cond_at_least: Checking "path_length > 107UL" implies that "path_length" is at least 108 on the true branch.
Also see events: [overrun-local]
102  	  if (path_length > sizeof(data_.local.sun_path) - 1)
103  	  {
104  	    // The buffer is not large enough to store this address.
105  	    boost::system::error_code ec(boost::asio::error::name_too_long);
106  	    boost::asio::detail::throw_error(ec);
107  	  }
108  	
109  	  using namespace std; // For memcpy.
110  	  data_.local = boost::asio::detail::sockaddr_un_type();
111  	  data_.local.sun_family = AF_UNIX;
(3) Event cond_true: Condition "path_length > 0", taking true branch.
112  	  if (path_length > 0)
113  	    memcpy(data_.local.sun_path, path_name, path_length);
114  	  path_length_ = path_length;
115  	
116  	  // NUL-terminate normal path names. Names that start with a NUL are in the
117  	  // UNIX domain protocol's "abstract namespace" and are not NUL-terminated.
(4) Event cond_true: Condition "path_length > 0", taking true branch.
(5) Event cond_true: Condition "this->data_.local.sun_path[0] == 0", taking true branch.
118  	  if (path_length > 0 && data_.local.sun_path[0] == 0)
(6) Event overrun-local: Overrunning array "this->data_.local.sun_path" of 108 bytes at byte offset 108 using index "path_length" (which evaluates to 108).
Also see events: [cond_at_least]
119  	    data_.local.sun_path[path_length] = 0;
120  	}
121  	
122  	} // namespace detail
123  	} // namespace local
124  	} // namespace asio
125  	} // namespace boost
126  	
127  	#include <boost/asio/detail/pop_options.hpp>
128  	
129  	#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
130  	
131  	#endif // BOOST_ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP
132