include/boost/corosio/native/detail/make_err.hpp

91.7% Lines (22/24) 100.0% List of functions (1/1) 87.5% Branches (21/24)
make_err.hpp
f(x) Functions (1)
Line Branch TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco ([email protected])
3 // Copyright (c) 2026 Steve Gerbino
4 // Copyright (c) 2026 Michael Vandeberg
5 //
6 // Distributed under the Boost Software License, Version 1.0. (See accompanying
7 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // Official repository: https://github.com/cppalliance/corosio
10 //
11
12 #ifndef BOOST_COROSIO_NATIVE_DETAIL_MAKE_ERR_HPP
13 #define BOOST_COROSIO_NATIVE_DETAIL_MAKE_ERR_HPP
14
15 #include <boost/corosio/detail/config.hpp>
16 #include <boost/corosio/detail/platform.hpp>
17 #include <boost/capy/error.hpp>
18 #include <system_error>
19
20 #if BOOST_COROSIO_POSIX
21 #include <errno.h>
22 #else
23 #ifndef WIN32_LEAN_AND_MEAN
24 #define WIN32_LEAN_AND_MEAN
25 #endif
26 #include <windows.h>
27 #endif
28
29 namespace boost::corosio::detail {
30
31 #if BOOST_COROSIO_POSIX
32
33 /** Convert a POSIX errno value to std::error_code.
34
35 Maps ECANCELED to capy::error::canceled.
36
37 @param errn The errno value.
38 @return The corresponding std::error_code.
39 */
40 inline std::error_code
41 make_err(int errn) noexcept
42 {
43 if (errn == 0)
44 return {};
45
46 if (errn == ECANCELED)
47 return capy::error::canceled;
48
49 // Part of the portable wait contract; system_category's condition
50 // mapping varies by C++ runtime.
51 if (errn == ENOTSUP)
52 return std::make_error_code(std::errc::operation_not_supported);
53
54 return std::error_code(errn, std::system_category());
55 }
56
57 #else
58
59 /** Convert a Windows error code to std::error_code.
60
61 Maps ERROR_OPERATION_ABORTED and ERROR_CANCELLED to
62 capy::error::canceled, ERROR_HANDLE_EOF to capy::error::eof, and
63 the contracted WSA/Win32 codes to the `std::errc` conditions the
64 library promises. Every other code passes through
65 std::system_category().
66
67 ERROR_NETNAME_DELETED (64) is deliberately not mapped here: IOCP
68 delivers it both for a local closesocket() that cancels pending I/O
69 and for a remote RST, so it can only be disambiguated per operation
70 kind at the IOCP decode sites (see iocp_make_err in win_overlapped_op).
71
72 @param dwError The Windows error code (DWORD).
73 @return The corresponding std::error_code.
74 */
75 inline std::error_code
76 2630x make_err(unsigned long dwError) noexcept
77 {
78
2/2
✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 4 taken 2629 times.
2630x if (dwError == 0)
79 1x return {};
80
81
3/4
✓ Branch 4 → 5 taken 530 times.
✓ Branch 4 → 6 taken 2099 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 530 times.
2629x if (dwError == ERROR_OPERATION_ABORTED || dwError == ERROR_CANCELLED)
82 2099x return capy::error::canceled;
83
84
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 530 times.
530x if (dwError == ERROR_HANDLE_EOF)
85 ✗ return capy::error::eof;
86
87 // Part of the portable wait, adoption, bind, and seek contracts;
88 // system_category's condition mapping for WSA codes varies by
89 // toolchain.
90
2/2
✓ Branch 9 → 10 taken 12 times.
✓ Branch 9 → 11 taken 518 times.
530x if (dwError == WSAEOPNOTSUPP)
91 12x return std::make_error_code(std::errc::operation_not_supported);
92
2/2
✓ Branch 11 → 12 taken 90 times.
✓ Branch 11 → 13 taken 428 times.
518x if (dwError == WSAENOTSOCK)
93 90x return std::make_error_code(std::errc::not_a_socket);
94
2/2
✓ Branch 13 → 14 taken 32 times.
✓ Branch 13 → 15 taken 396 times.
428x if (dwError == WSAEAFNOSUPPORT)
95 32x return std::make_error_code(std::errc::address_family_not_supported);
96
2/2
✓ Branch 15 → 16 taken 4 times.
✓ Branch 15 → 17 taken 392 times.
396x if (dwError == WSAEPROTOTYPE)
97 4x return std::make_error_code(std::errc::wrong_protocol_type);
98
2/2
✓ Branch 17 → 18 taken 11 times.
✓ Branch 17 → 19 taken 381 times.
392x if (dwError == WSAEADDRINUSE)
99 11x return std::make_error_code(std::errc::address_in_use);
100
2/2
✓ Branch 19 → 20 taken 7 times.
✓ Branch 19 → 21 taken 374 times.
381x if (dwError == WSAEADDRNOTAVAIL)
101 7x return std::make_error_code(std::errc::address_not_available);
102
2/2
✓ Branch 21 → 22 taken 3 times.
✓ Branch 21 → 23 taken 371 times.
374x if (dwError == ERROR_NEGATIVE_SEEK)
103 3x return std::make_error_code(std::errc::invalid_argument);
104 // A thread the system will not give is the same retryable
105 // condition POSIX spells EAGAIN, which is what the contract
106 // promises; no toolchain maps the Win32 spelling to it.
107
1/2
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 25 taken 371 times.
371x if (dwError == ERROR_MAX_THRDS_REACHED)
108 ✗ return std::make_error_code(std::errc::resource_unavailable_try_again);
109
110 371x return std::error_code(static_cast<int>(dwError), std::system_category());
111 }
112
113 #endif
114
115 } // namespace boost::corosio::detail
116
117 #endif
118