98.31% Lines (58/59) 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/detail/except.hpp>  
16   #include <boost/corosio/error.hpp> 15   #include <boost/corosio/error.hpp>
17   #include <boost/corosio/detail/local_stream_service.hpp> 16   #include <boost/corosio/detail/local_stream_service.hpp>
18   17  
19   #include "src/detail/use_backend_service.hpp" 18   #include "src/detail/use_backend_service.hpp"
20   #include <boost/corosio/native/detail/make_err.hpp> 19   #include <boost/corosio/native/detail/make_err.hpp>
21   20  
22   #if BOOST_COROSIO_POSIX 21   #if BOOST_COROSIO_POSIX
23   #include <sys/ioctl.h> 22   #include <sys/ioctl.h>
24   #include <sys/socket.h> 23   #include <sys/socket.h>
25   #elif BOOST_COROSIO_HAS_IOCP 24   #elif BOOST_COROSIO_HAS_IOCP
26   #include <boost/corosio/native/detail/iocp/win_windows.hpp> 25   #include <boost/corosio/native/detail/iocp/win_windows.hpp>
27   #ifndef AF_UNIX 26   #ifndef AF_UNIX
28   #define AF_UNIX 1 27   #define AF_UNIX 1
29   #endif 28   #endif
30   #endif 29   #endif
31   30  
32   namespace boost::corosio { 31   namespace boost::corosio {
33   32  
HITCBC 34   432 local_stream_socket::~local_stream_socket() 33   440 local_stream_socket::~local_stream_socket()
35   { 34   {
HITCBC 36   432 close(); 35   440 close();
HITCBC 37   432 } 36   440 }
38   37  
HITCBC 39   374 local_stream_socket::local_stream_socket(capy::execution_context& ctx) 38   378 local_stream_socket::local_stream_socket(capy::execution_context& ctx)
HITCBC 40   374 : io_object(handle( 39   378 : io_object(handle(
41   ctx, 40   ctx,
42   detail::use_backend_service< 41   detail::use_backend_service<
43   detail::local_stream_service_of, 42   detail::local_stream_service_of,
HITCBC 44   748 detail::local_stream_service>(ctx))) 43   756 detail::local_stream_service>(ctx)))
45   { 44   {
HITCBC 46   374 } 45   378 }
47   46  
48   std::error_code 47   std::error_code
HITCBC 49   53 local_stream_socket::open() noexcept 48   53 local_stream_socket::open() noexcept
50   { 49   {
HITCBC 51   53 if (is_open()) 50   53 if (is_open())
MISUBC 52   ✗ return {}; 51   ✗ return {};
HITCBC 53   53 return open_for_family(AF_UNIX, SOCK_STREAM, 0); 52   53 return open_for_family(AF_UNIX, SOCK_STREAM, 0);
54   } 53   }
55   54  
56   std::error_code 55   std::error_code
HITCBC 57   53 local_stream_socket::open_for_family( 56   53 local_stream_socket::open_for_family(
58   int family, int type, int protocol) noexcept 57   int family, int type, int protocol) noexcept
59   { 58   {
HITCBC 60   53 auto& svc = static_cast<detail::local_stream_service&>(h_.service()); 59   53 auto& svc = static_cast<detail::local_stream_service&>(h_.service());
HITCBC 61   53 std::error_code ec = svc.open_socket( 60   53 std::error_code ec = svc.open_socket(
HITCBC 62   53 static_cast<local_stream_socket::implementation&>(*h_.get()), family, 61   53 static_cast<local_stream_socket::implementation&>(*h_.get()), family,
63   type, protocol); 62   type, protocol);
HITCBC 64   53 return ec; 63   53 return ec;
65   } 64   }
66   65  
67   void 66   void
HITCBC 68   453 local_stream_socket::close() noexcept 67   461 local_stream_socket::close() noexcept
69   { 68   {
HITCBC 70   453 if (!is_open()) 69   461 if (!is_open())
HITCBC 71   213 return; 70   221 return;
HITCBC 72   240 h_.service().close(h_); 71   240 h_.service().close(h_);
73   } 72   }
74   73  
75   void 74   void
HITCBC 76   10 local_stream_socket::cancel() noexcept 75   10 local_stream_socket::cancel() noexcept
77   { 76   {
HITCBC 78   10 if (!is_open()) 77   10 if (!is_open())
HITCBC 79   2 return; 78   2 return;
HITCBC 80   8 get().cancel(); 79   8 get().cancel();
81   } 80   }
82   81  
83   std::error_code 82   std::error_code
HITCBC 84   6 local_stream_socket::shutdown(shutdown_type what) noexcept 83   6 local_stream_socket::shutdown(shutdown_type what) noexcept
85   { 84   {
HITCBC 86   6 if (!is_open()) 85   6 if (!is_open())
HITCBC 87   2 return make_error_code(std::errc::bad_file_descriptor); 86   2 return make_error_code(std::errc::bad_file_descriptor);
HITCBC 88   4 return get().shutdown(what); 87   4 return get().shutdown(what);
89   } 88   }
90   89  
91   std::error_code 90   std::error_code
HITCBC 92   191 local_stream_socket::assign(native_handle_type fd) noexcept 91   191 local_stream_socket::assign(native_handle_type fd) noexcept
93   { 92   {
HITCBC 94   191 if (is_open()) 93   191 if (is_open())
HITCBC 95   8 return make_error_code(error::already_open); 94   8 return make_error_code(error::already_open);
HITCBC 96   183 auto& svc = static_cast<detail::local_stream_service&>(h_.service()); 95   183 auto& svc = static_cast<detail::local_stream_service&>(h_.service());
HITCBC 97   183 std::error_code ec = svc.assign_socket( 96   183 std::error_code ec = svc.assign_socket(
HITCBC 98   183 static_cast<local_stream_socket::implementation&>(*h_.get()), fd); 97   183 static_cast<local_stream_socket::implementation&>(*h_.get()), fd);
HITCBC 99   183 return ec; 98   183 return ec;
100   } 99   }
101   100  
102   native_handle_type 101   native_handle_type
HITCBC 103   31 local_stream_socket::native_handle() const noexcept 102   31 local_stream_socket::native_handle() const noexcept
104   { 103   {
HITCBC 105   31 if (!is_open()) 104   31 if (!is_open())
106   #if BOOST_COROSIO_HAS_IOCP 105   #if BOOST_COROSIO_HAS_IOCP
107   return ~native_handle_type(0); 106   return ~native_handle_type(0);
108   #else 107   #else
HITCBC 109   2 return -1; 108   2 return -1;
110   #endif 109   #endif
HITCBC 111   29 return get().native_handle(); 110   29 return get().native_handle();
112   } 111   }
113   112  
114 - native_handle_type 113 + capy::results<native_handle_type>
HITCBC 115 - 8 local_stream_socket::release() 114 + 8 local_stream_socket::release() noexcept
116   { 115   {
HITCBC 117   8 if (!is_open()) 116   8 if (!is_open())
ECB 118 - 2 detail::throw_system_error( 117 + return {
HITCBC 119   2 make_error_code(std::errc::bad_file_descriptor), 118   4 make_error_code(std::errc::bad_file_descriptor),
HITGIC 120 - "local_stream_socket::release"); 119 + 2 detail::invalid_native_handle};
HITCBC 121 - 6 return get().release_socket(); 120 + 6 return {std::error_code{}, get().release_socket()};
122   } 121   }
123   122  
124 - std::size_t 123 + capy::results<std::size_t>
HITCBC 125 - 11 local_stream_socket::available() const 124 + 11 local_stream_socket::available() const noexcept
126   { 125   {
HITCBC 127   11 if (!is_open()) 126   11 if (!is_open())
HITCBC 128 - 2 detail::throw_system_error( 127 + 2 return {make_error_code(std::errc::bad_file_descriptor), 0};
DCB 129 - 4 make_error_code(std::errc::bad_file_descriptor),  
130 - "local_stream_socket::available");  
131   #if BOOST_COROSIO_HAS_IOCP 128   #if BOOST_COROSIO_HAS_IOCP
132   u_long value = 0; 129   u_long value = 0;
133   if (::ioctlsocket(static_cast<SOCKET>(native_handle()), FIONREAD, &value) != 130   if (::ioctlsocket(static_cast<SOCKET>(native_handle()), FIONREAD, &value) !=
134   0) 131   0)
135 - detail::throw_system_error( 132 + return {
136   detail::make_err(static_cast<unsigned long>(::WSAGetLastError())), 133   detail::make_err(static_cast<unsigned long>(::WSAGetLastError())),
137 - "local_stream_socket::available"); 134 + 0};
138 - return static_cast<std::size_t>(value); 135 + return {std::error_code{}, static_cast<std::size_t>(value)};
139   #else 136   #else
HITCBC 140   9 int value = 0; 137   9 int value = 0;
HITCBC 141   9 if (::ioctl(native_handle(), FIONREAD, &value) < 0) 138   9 if (::ioctl(native_handle(), FIONREAD, &value) < 0)
HITCBC 142 - 5 detail::throw_system_error( 139 + 5 return {detail::make_err(errno), 0};
HITCBC 143 - 10 detail::make_err(errno), "local_stream_socket::available"); 140 + 4 return {std::error_code{}, static_cast<std::size_t>(value)};
DCB 144 - 4 return static_cast<std::size_t>(value);  
145   #endif 141   #endif
146   } 142   }
147   143  
148   local_endpoint 144   local_endpoint
HITCBC 149   6 local_stream_socket::local_endpoint() const noexcept 145   6 local_stream_socket::local_endpoint() const noexcept
150   { 146   {
HITCBC 151   6 if (!is_open()) 147   6 if (!is_open())
HITCBC 152   2 return corosio::local_endpoint{}; 148   2 return corosio::local_endpoint{};
HITCBC 153   4 return get().local_endpoint(); 149   4 return get().local_endpoint();
154   } 150   }
155   151  
156   local_endpoint 152   local_endpoint
HITCBC 157   6 local_stream_socket::remote_endpoint() const noexcept 153   6 local_stream_socket::remote_endpoint() const noexcept
158   { 154   {
HITCBC 159   6 if (!is_open()) 155   6 if (!is_open())
HITCBC 160   2 return corosio::local_endpoint{}; 156   2 return corosio::local_endpoint{};
HITCBC 161   4 return get().remote_endpoint(); 157   4 return get().remote_endpoint();
162   } 158   }
163   159  
164   } // namespace boost::corosio 160   } // namespace boost::corosio
165   161  
166   #endif // BOOST_COROSIO_POSIX || BOOST_COROSIO_HAS_IOCP 162   #endif // BOOST_COROSIO_POSIX || BOOST_COROSIO_HAS_IOCP