1  
//
1  
//
2  
// Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3  
// Copyright (c) 2026 Steve Gerbino
3  
// Copyright (c) 2026 Steve Gerbino
4  
//
4  
//
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  
//
7  
//
8  
// Official repository: https://github.com/cppalliance/corosio
8  
// Official repository: https://github.com/cppalliance/corosio
9  
//
9  
//
10  

10  

11  
#ifndef BOOST_COROSIO_DETAIL_MAKE_ERR_HPP
11  
#ifndef BOOST_COROSIO_DETAIL_MAKE_ERR_HPP
12  
#define BOOST_COROSIO_DETAIL_MAKE_ERR_HPP
12  
#define BOOST_COROSIO_DETAIL_MAKE_ERR_HPP
13  

13  

14  
#include <boost/corosio/detail/config.hpp>
14  
#include <boost/corosio/detail/config.hpp>
15  
#include <boost/corosio/detail/platform.hpp>
15  
#include <boost/corosio/detail/platform.hpp>
16  
#include <boost/capy/error.hpp>
16  
#include <boost/capy/error.hpp>
17  
#include <system_error>
17  
#include <system_error>
18  

18  

19  
#if BOOST_COROSIO_POSIX
19  
#if BOOST_COROSIO_POSIX
20  
#include <errno.h>
20  
#include <errno.h>
21  
#else
21  
#else
22  
#ifndef WIN32_LEAN_AND_MEAN
22  
#ifndef WIN32_LEAN_AND_MEAN
23  
#define WIN32_LEAN_AND_MEAN
23  
#define WIN32_LEAN_AND_MEAN
24  
#endif
24  
#endif
25  
#include <Windows.h>
25  
#include <Windows.h>
26  
#endif
26  
#endif
27  

27  

28  
namespace boost::corosio::detail {
28  
namespace boost::corosio::detail {
29  

29  

30  
#if BOOST_COROSIO_POSIX
30  
#if BOOST_COROSIO_POSIX
31  

31  

32  
/** Convert a POSIX errno value to std::error_code.
32  
/** Convert a POSIX errno value to std::error_code.
33  

33  

34  
    Maps ECANCELED to capy::error::canceled.
34  
    Maps ECANCELED to capy::error::canceled.
35  

35  

36  
    @param errn The errno value.
36  
    @param errn The errno value.
37  
    @return The corresponding std::error_code.
37  
    @return The corresponding std::error_code.
38  
*/
38  
*/
39  
inline std::error_code
39  
inline std::error_code
40  
make_err(int errn) noexcept
40  
make_err(int errn) noexcept
41  
{
41  
{
42  
    if (errn == 0)
42  
    if (errn == 0)
43  
        return {};
43  
        return {};
44  

44  

45  
    if (errn == ECANCELED)
45  
    if (errn == ECANCELED)
46  
        return capy::error::canceled;
46  
        return capy::error::canceled;
47  

47  

48  
    return std::error_code(errn, std::system_category());
48  
    return std::error_code(errn, std::system_category());
49  
}
49  
}
50  

50  

51  
#else
51  
#else
52  

52  

53  
/** Convert a Windows error code to std::error_code.
53  
/** Convert a Windows error code to std::error_code.
54  

54  

55  
    Maps ERROR_OPERATION_ABORTED, ERROR_CANCELLED, and
55  
    Maps ERROR_OPERATION_ABORTED, ERROR_CANCELLED, and
56  
    ERROR_NETNAME_DELETED to capy::error::canceled.
56  
    ERROR_NETNAME_DELETED to capy::error::canceled.
57  
    Maps ERROR_HANDLE_EOF to capy::error::eof.
57  
    Maps ERROR_HANDLE_EOF to capy::error::eof.
58  

58  

59  
    ERROR_NETNAME_DELETED (64) is what IOCP actually delivers
59  
    ERROR_NETNAME_DELETED (64) is what IOCP actually delivers
60  
    when closesocket() cancels pending overlapped I/O, despite
60  
    when closesocket() cancels pending overlapped I/O, despite
61  
    MSDN documenting ERROR_OPERATION_ABORTED for that case.
61  
    MSDN documenting ERROR_OPERATION_ABORTED for that case.
62  

62  

63  
    @param dwError The Windows error code (DWORD).
63  
    @param dwError The Windows error code (DWORD).
64  
    @return The corresponding std::error_code.
64  
    @return The corresponding std::error_code.
65  
*/
65  
*/
66  
inline std::error_code
66  
inline std::error_code
67  
make_err(unsigned long dwError) noexcept
67  
make_err(unsigned long dwError) noexcept
68  
{
68  
{
69  
    if (dwError == 0)
69  
    if (dwError == 0)
70  
        return {};
70  
        return {};
71  

71  

72  
    if (dwError == ERROR_OPERATION_ABORTED || dwError == ERROR_CANCELLED ||
72  
    if (dwError == ERROR_OPERATION_ABORTED || dwError == ERROR_CANCELLED ||
73  
        dwError == ERROR_NETNAME_DELETED)
73  
        dwError == ERROR_NETNAME_DELETED)
74  
        return capy::error::canceled;
74  
        return capy::error::canceled;
75  

75  

76  
    if (dwError == ERROR_HANDLE_EOF)
76  
    if (dwError == ERROR_HANDLE_EOF)
77  
        return capy::error::eof;
77  
        return capy::error::eof;
78  

78  

79  
    return std::error_code(static_cast<int>(dwError), std::system_category());
79  
    return std::error_code(static_cast<int>(dwError), std::system_category());
80  
}
80  
}
81  

81  

82  
#endif
82  
#endif
83  

83  

84  
} // namespace boost::corosio::detail
84  
} // namespace boost::corosio::detail
85  

85  

86  
#endif
86  
#endif