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

75.0% Lines (6/0/8) 100.0% List of functions (1/0/1)
make_err.hpp
f(x) Functions (1)
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
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 518x make_err(int errn) noexcept
42 {
43 518x if (errn == 0)
44 return {};
45
46 518x 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 518x if (errn == ENOTSUP)
52 24x return std::make_error_code(std::errc::operation_not_supported);
53
54 494x 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 make_err(unsigned long dwError) noexcept
77 {
78 if (dwError == 0)
79 return {};
80
81 if (dwError == ERROR_OPERATION_ABORTED || dwError == ERROR_CANCELLED)
82 return capy::error::canceled;
83
84 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 if (dwError == WSAEOPNOTSUPP)
91 return std::make_error_code(std::errc::operation_not_supported);
92 if (dwError == WSAENOTSOCK)
93 return std::make_error_code(std::errc::not_a_socket);
94 if (dwError == WSAEAFNOSUPPORT)
95 return std::make_error_code(
96 std::errc::address_family_not_supported);
97 if (dwError == WSAEPROTOTYPE)
98 return std::make_error_code(std::errc::wrong_protocol_type);
99 if (dwError == WSAEADDRINUSE)
100 return std::make_error_code(std::errc::address_in_use);
101 if (dwError == WSAEADDRNOTAVAIL)
102 return std::make_error_code(std::errc::address_not_available);
103 if (dwError == ERROR_NEGATIVE_SEEK)
104 return std::make_error_code(std::errc::invalid_argument);
105 // A thread the system will not give is the same retryable
106 // condition POSIX spells EAGAIN, which is what the contract
107 // promises; no toolchain maps the Win32 spelling to it.
108 if (dwError == ERROR_MAX_THRDS_REACHED)
109 return std::make_error_code(
110 std::errc::resource_unavailable_try_again);
111
112 return std::error_code(static_cast<int>(dwError), std::system_category());
113 }
114
115 #endif
116
117 } // namespace boost::corosio::detail
118
119 #endif
120