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