98.36% Lines (60/61) 100.00% Functions (13/13)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2026 Michael Vandeberg 2   // Copyright (c) 2026 Michael Vandeberg
3   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 4   // Distributed under the Boost Software License, Version 1.0. (See accompanying
5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/cppalliance/corosio 7   // Official repository: https://github.com/cppalliance/corosio
8   // 8   //
9   9  
10   #include <boost/corosio/detail/platform.hpp> 10   #include <boost/corosio/detail/platform.hpp>
11   11  
12   #if BOOST_COROSIO_POSIX || BOOST_COROSIO_HAS_IOCP 12   #if BOOST_COROSIO_POSIX || BOOST_COROSIO_HAS_IOCP
13   13  
14   #include <boost/corosio/local_stream_socket.hpp> 14   #include <boost/corosio/local_stream_socket.hpp>
  15 + #include <boost/corosio/error.hpp>
15   #include <boost/corosio/detail/except.hpp> 16   #include <boost/corosio/detail/except.hpp>
16   #include <boost/corosio/detail/local_stream_service.hpp> 17   #include <boost/corosio/detail/local_stream_service.hpp>
17   18  
18   #include "src/detail/use_backend_service.hpp" 19   #include "src/detail/use_backend_service.hpp"
19   #include <boost/corosio/native/detail/make_err.hpp> 20   #include <boost/corosio/native/detail/make_err.hpp>
20   21  
21   #if BOOST_COROSIO_POSIX 22   #if BOOST_COROSIO_POSIX
22   #include <sys/ioctl.h> 23   #include <sys/ioctl.h>
23   #include <sys/socket.h> 24   #include <sys/socket.h>
24   #elif BOOST_COROSIO_HAS_IOCP 25   #elif BOOST_COROSIO_HAS_IOCP
25   #include <boost/corosio/native/detail/iocp/win_windows.hpp> 26   #include <boost/corosio/native/detail/iocp/win_windows.hpp>
26   #ifndef AF_UNIX 27   #ifndef AF_UNIX
27   #define AF_UNIX 1 28   #define AF_UNIX 1
28   #endif 29   #endif
29   #endif 30   #endif
30   31  
31   namespace boost::corosio { 32   namespace boost::corosio {
32   33  
HITCBC 33   344 local_stream_socket::~local_stream_socket() 34   348 local_stream_socket::~local_stream_socket()
34   { 35   {
HITCBC 35   344 close(); 36   348 close();
HITCBC 36   344 } 37   348 }
37   38  
HITCBC 38   286 local_stream_socket::local_stream_socket(capy::execution_context& ctx) 39   290 local_stream_socket::local_stream_socket(capy::execution_context& ctx)
HITCBC 39   286 : io_object(handle( 40   290 : io_object(handle(
40   ctx, 41   ctx,
41   detail::use_backend_service< 42   detail::use_backend_service<
42   detail::local_stream_service_of, 43   detail::local_stream_service_of,
HITCBC 43   572 detail::local_stream_service>(ctx))) 44   580 detail::local_stream_service>(ctx)))
44   { 45   {
HITCBC 45   286 } 46   290 }
46   47  
47   std::error_code 48   std::error_code
HITCBC 48   51 local_stream_socket::open() noexcept 49   51 local_stream_socket::open() noexcept
49   { 50   {
HITCBC 50   51 if (is_open()) 51   51 if (is_open())
MISUBC 51   ✗ return {}; 52   ✗ return {};
HITCBC 52   51 return open_for_family(AF_UNIX, SOCK_STREAM, 0); 53   51 return open_for_family(AF_UNIX, SOCK_STREAM, 0);
53   } 54   }
54   55  
55   std::error_code 56   std::error_code
HITCBC 56   51 local_stream_socket::open_for_family( 57   51 local_stream_socket::open_for_family(
57   int family, int type, int protocol) noexcept 58   int family, int type, int protocol) noexcept
58   { 59   {
HITCBC 59   51 auto& svc = static_cast<detail::local_stream_service&>(h_.service()); 60   51 auto& svc = static_cast<detail::local_stream_service&>(h_.service());
HITCBC 60   51 std::error_code ec = svc.open_socket( 61   51 std::error_code ec = svc.open_socket(
HITCBC 61   51 static_cast<local_stream_socket::implementation&>(*h_.get()), family, 62   51 static_cast<local_stream_socket::implementation&>(*h_.get()), family,
62   type, protocol); 63   type, protocol);
HITCBC 63   51 return ec; 64   51 return ec;
64   } 65   }
65   66  
66   void 67   void
HITCBC 67   357 local_stream_socket::close() noexcept 68   363 local_stream_socket::close() noexcept
68   { 69   {
HITCBC 69   357 if (!is_open()) 70   363 if (!is_open())
HITCBC 70   135 return; 71   137 return;
HITCBC 71   222 h_.service().close(h_); 72   226 h_.service().close(h_);
72   } 73   }
73   74  
74   void 75   void
HITCBC 75   8 local_stream_socket::cancel() noexcept 76   8 local_stream_socket::cancel() noexcept
76   { 77   {
HITCBC 77   8 if (!is_open()) 78   8 if (!is_open())
HITCBC 78   2 return; 79   2 return;
HITCBC 79   6 get().cancel(); 80   6 get().cancel();
80   } 81   }
81   82  
82   std::error_code 83   std::error_code
HITCBC 83   6 local_stream_socket::shutdown(shutdown_type what) noexcept 84   6 local_stream_socket::shutdown(shutdown_type what) noexcept
84   { 85   {
HITCBC 85   6 if (!is_open()) 86   6 if (!is_open())
HITCBC 86   2 return make_error_code(std::errc::bad_file_descriptor); 87   2 return make_error_code(std::errc::bad_file_descriptor);
HITCBC 87   4 return get().shutdown(what); 88   4 return get().shutdown(what);
88   } 89   }
89   90  
90   std::error_code 91   std::error_code
HITCBC 91   173 local_stream_socket::assign(native_handle_type fd) noexcept 92   179 local_stream_socket::assign(native_handle_type fd) noexcept
92   { 93   {
HITGNC   94 + 179 if (is_open())
HITGNC   95 + 8 return make_error_code(error::already_open);
HITCBC 93   173 auto& svc = static_cast<detail::local_stream_service&>(h_.service()); 96   171 auto& svc = static_cast<detail::local_stream_service&>(h_.service());
HITCBC 94   173 std::error_code ec = svc.assign_socket( 97   171 std::error_code ec = svc.assign_socket(
HITCBC 95   173 static_cast<local_stream_socket::implementation&>(*h_.get()), fd); 98   171 static_cast<local_stream_socket::implementation&>(*h_.get()), fd);
HITCBC 96   173 return ec; 99   171 return ec;
97   } 100   }
98   101  
99   native_handle_type 102   native_handle_type
HITCBC 100   25 local_stream_socket::native_handle() const noexcept 103   31 local_stream_socket::native_handle() const noexcept
101   { 104   {
HITCBC 102   25 if (!is_open()) 105   31 if (!is_open())
103   #if BOOST_COROSIO_HAS_IOCP 106   #if BOOST_COROSIO_HAS_IOCP
104   return ~native_handle_type(0); 107   return ~native_handle_type(0);
105   #else 108   #else
HITCBC 106   2 return -1; 109   2 return -1;
107   #endif 110   #endif
HITCBC 108   23 return get().native_handle(); 111   29 return get().native_handle();
109   } 112   }
110   113  
111   native_handle_type 114   native_handle_type
HITCBC 112   6 local_stream_socket::release() 115   6 local_stream_socket::release()
113   { 116   {
HITCBC 114   6 if (!is_open()) 117   6 if (!is_open())
HITCBC 115   2 detail::throw_system_error( 118   2 detail::throw_system_error(
HITCBC 116   2 make_error_code(std::errc::bad_file_descriptor), 119   2 make_error_code(std::errc::bad_file_descriptor),
117   "local_stream_socket::release"); 120   "local_stream_socket::release");
HITCBC 118   4 return get().release_socket(); 121   4 return get().release_socket();
119   } 122   }
120   123  
121   std::size_t 124   std::size_t
HITCBC 122   11 local_stream_socket::available() const 125   11 local_stream_socket::available() const
123   { 126   {
HITCBC 124   11 if (!is_open()) 127   11 if (!is_open())
HITCBC 125   2 detail::throw_system_error( 128   2 detail::throw_system_error(
HITCBC 126   4 make_error_code(std::errc::bad_file_descriptor), 129   4 make_error_code(std::errc::bad_file_descriptor),
127   "local_stream_socket::available"); 130   "local_stream_socket::available");
128   #if BOOST_COROSIO_HAS_IOCP 131   #if BOOST_COROSIO_HAS_IOCP
129   u_long value = 0; 132   u_long value = 0;
130   if (::ioctlsocket(static_cast<SOCKET>(native_handle()), FIONREAD, &value) != 133   if (::ioctlsocket(static_cast<SOCKET>(native_handle()), FIONREAD, &value) !=
131   0) 134   0)
132   detail::throw_system_error( 135   detail::throw_system_error(
133   detail::make_err(static_cast<unsigned long>(::WSAGetLastError())), 136   detail::make_err(static_cast<unsigned long>(::WSAGetLastError())),
134   "local_stream_socket::available"); 137   "local_stream_socket::available");
135   return static_cast<std::size_t>(value); 138   return static_cast<std::size_t>(value);
136   #else 139   #else
HITCBC 137   9 int value = 0; 140   9 int value = 0;
HITCBC 138   9 if (::ioctl(native_handle(), FIONREAD, &value) < 0) 141   9 if (::ioctl(native_handle(), FIONREAD, &value) < 0)
HITCBC 139   5 detail::throw_system_error( 142   5 detail::throw_system_error(
HITCBC 140   10 detail::make_err(errno), "local_stream_socket::available"); 143   10 detail::make_err(errno), "local_stream_socket::available");
HITCBC 141   4 return static_cast<std::size_t>(value); 144   4 return static_cast<std::size_t>(value);
142   #endif 145   #endif
143   } 146   }
144   147  
145   local_endpoint 148   local_endpoint
HITCBC 146   6 local_stream_socket::local_endpoint() const noexcept 149   6 local_stream_socket::local_endpoint() const noexcept
147   { 150   {
HITCBC 148   6 if (!is_open()) 151   6 if (!is_open())
HITCBC 149   2 return corosio::local_endpoint{}; 152   2 return corosio::local_endpoint{};
HITCBC 150   4 return get().local_endpoint(); 153   4 return get().local_endpoint();
151   } 154   }
152   155  
153   local_endpoint 156   local_endpoint
HITCBC 154   6 local_stream_socket::remote_endpoint() const noexcept 157   6 local_stream_socket::remote_endpoint() const noexcept
155   { 158   {
HITCBC 156   6 if (!is_open()) 159   6 if (!is_open())
HITCBC 157   2 return corosio::local_endpoint{}; 160   2 return corosio::local_endpoint{};
HITCBC 158   4 return get().remote_endpoint(); 161   4 return get().remote_endpoint();
159   } 162   }
160   163  
161   } // namespace boost::corosio 164   } // namespace boost::corosio
162   165  
163   #endif // BOOST_COROSIO_POSIX || BOOST_COROSIO_HAS_IOCP 166   #endif // BOOST_COROSIO_POSIX || BOOST_COROSIO_HAS_IOCP