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