TLA Line data 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 HIT 518 : make_err(int errn) noexcept
42 : {
43 518 : if (errn == 0)
44 MIS 0 : return {};
45 :
46 HIT 518 : if (errn == ECANCELED)
47 MIS 0 : return capy::error::canceled;
48 :
49 : // Part of the portable wait contract; system_category's condition
50 : // mapping varies by C++ runtime.
51 HIT 518 : if (errn == ENOTSUP)
52 24 : return std::make_error_code(std::errc::operation_not_supported);
53 :
54 494 : 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
|