]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | // error_handling.hpp --------------------------------------------------------------------// |
2 | ||
3 | // Copyright 2002-2009, 2014 Beman Dawes | |
4 | // Copyright 2019 Andrey Semashev | |
5 | ||
6 | // Distributed under the Boost Software License, Version 1.0. | |
7 | // See http://www.boost.org/LICENSE_1_0.txt | |
8 | ||
9 | // See library home page at http://www.boost.org/libs/filesystem | |
10 | ||
11 | //--------------------------------------------------------------------------------------// | |
12 | ||
1e59de90 TL |
13 | #ifndef BOOST_FILESYSTEM_SRC_ERROR_HANDLING_HPP_ |
14 | #define BOOST_FILESYSTEM_SRC_ERROR_HANDLING_HPP_ | |
92f5a8d4 TL |
15 | |
16 | #include <cerrno> | |
17 | #include <boost/system/error_code.hpp> | |
18 | #include <boost/filesystem/config.hpp> | |
19 | #include <boost/filesystem/exception.hpp> | |
20 | ||
21 | #if defined(BOOST_WINDOWS_API) | |
22 | #include <boost/winapi/basic_types.hpp> | |
23 | #include <boost/winapi/get_last_error.hpp> | |
24 | #include <boost/winapi/error_codes.hpp> | |
25 | #endif | |
26 | ||
27 | namespace boost { | |
28 | namespace filesystem { | |
29 | ||
30 | #if defined(BOOST_POSIX_API) | |
31 | ||
32 | typedef int err_t; | |
33 | ||
34 | // POSIX uses a 0 return to indicate success | |
1e59de90 | 35 | #define BOOST_ERRNO errno |
92f5a8d4 | 36 | |
20effc67 | 37 | #define BOOST_ERROR_FILE_NOT_FOUND ENOENT |
92f5a8d4 | 38 | #define BOOST_ERROR_ALREADY_EXISTS EEXIST |
20effc67 | 39 | #define BOOST_ERROR_NOT_SUPPORTED ENOSYS |
92f5a8d4 TL |
40 | |
41 | #else | |
42 | ||
43 | typedef boost::winapi::DWORD_ err_t; | |
44 | ||
45 | // Windows uses a non-0 return to indicate success | |
1e59de90 | 46 | #define BOOST_ERRNO boost::winapi::GetLastError() |
92f5a8d4 | 47 | |
20effc67 | 48 | #define BOOST_ERROR_FILE_NOT_FOUND boost::winapi::ERROR_FILE_NOT_FOUND_ |
92f5a8d4 TL |
49 | #define BOOST_ERROR_ALREADY_EXISTS boost::winapi::ERROR_ALREADY_EXISTS_ |
50 | #define BOOST_ERROR_NOT_SUPPORTED boost::winapi::ERROR_NOT_SUPPORTED_ | |
51 | ||
1e59de90 TL |
52 | // Note: Legacy MinGW doesn't have ntstatus.h and doesn't define NTSTATUS error codes other than STATUS_SUCCESS. |
53 | #if !defined(NT_SUCCESS) | |
54 | #define NT_SUCCESS(Status) (((boost::winapi::NTSTATUS_)(Status)) >= 0) | |
55 | #endif | |
56 | #if !defined(STATUS_SUCCESS) | |
57 | #define STATUS_SUCCESS ((boost::winapi::NTSTATUS_)0x00000000l) | |
58 | #endif | |
59 | #if !defined(STATUS_NOT_IMPLEMENTED) | |
60 | #define STATUS_NOT_IMPLEMENTED ((boost::winapi::NTSTATUS_)0xC0000002l) | |
61 | #endif | |
62 | #if !defined(STATUS_INVALID_INFO_CLASS) | |
63 | #define STATUS_INVALID_INFO_CLASS ((boost::winapi::NTSTATUS_)0xC0000003l) | |
64 | #endif | |
65 | #if !defined(STATUS_INVALID_HANDLE) | |
66 | #define STATUS_INVALID_HANDLE ((boost::winapi::NTSTATUS_)0xC0000008l) | |
67 | #endif | |
68 | #if !defined(STATUS_INVALID_PARAMETER) | |
69 | #define STATUS_INVALID_PARAMETER ((boost::winapi::NTSTATUS_)0xC000000Dl) | |
70 | #endif | |
71 | #if !defined(STATUS_NO_SUCH_DEVICE) | |
72 | #define STATUS_NO_SUCH_DEVICE ((boost::winapi::NTSTATUS_)0xC000000El) | |
73 | #endif | |
74 | #if !defined(STATUS_NO_SUCH_FILE) | |
75 | #define STATUS_NO_SUCH_FILE ((boost::winapi::NTSTATUS_)0xC000000Fl) | |
76 | #endif | |
77 | #if !defined(STATUS_NO_MORE_FILES) | |
78 | #define STATUS_NO_MORE_FILES ((boost::winapi::NTSTATUS_)0x80000006l) | |
79 | #endif | |
80 | #if !defined(STATUS_BUFFER_OVERFLOW) | |
81 | #define STATUS_BUFFER_OVERFLOW ((boost::winapi::NTSTATUS_)0x80000005l) | |
82 | #endif | |
83 | #if !defined(STATUS_NO_MEMORY) | |
84 | #define STATUS_NO_MEMORY ((boost::winapi::NTSTATUS_)0xC0000017l) | |
85 | #endif | |
86 | #if !defined(STATUS_ACCESS_DENIED) | |
87 | #define STATUS_ACCESS_DENIED ((boost::winapi::NTSTATUS_)0xC0000022l) | |
88 | #endif | |
89 | ||
90 | //! Converts NTSTATUS error codes to Win32 error codes for reporting | |
91 | inline boost::winapi::DWORD_ translate_ntstatus(boost::winapi::NTSTATUS_ status) | |
92 | { | |
93 | // We have to cast to unsigned integral type to avoid signed overflow and narrowing conversion in the constants. | |
94 | switch (static_cast< boost::winapi::ULONG_ >(status)) | |
95 | { | |
96 | case static_cast< boost::winapi::ULONG_ >(STATUS_NO_MEMORY): | |
97 | return boost::winapi::ERROR_OUTOFMEMORY_; | |
98 | case static_cast< boost::winapi::ULONG_ >(STATUS_BUFFER_OVERFLOW): | |
99 | return boost::winapi::ERROR_BUFFER_OVERFLOW_; | |
100 | case static_cast< boost::winapi::ULONG_ >(STATUS_INVALID_HANDLE): | |
101 | return boost::winapi::ERROR_INVALID_HANDLE_; | |
102 | case static_cast< boost::winapi::ULONG_ >(STATUS_INVALID_PARAMETER): | |
103 | return boost::winapi::ERROR_INVALID_PARAMETER_; | |
104 | case static_cast< boost::winapi::ULONG_ >(STATUS_NO_MORE_FILES): | |
105 | return boost::winapi::ERROR_NO_MORE_FILES_; | |
106 | case static_cast< boost::winapi::ULONG_ >(STATUS_NO_SUCH_DEVICE): | |
107 | return boost::winapi::ERROR_DEV_NOT_EXIST_; | |
108 | case static_cast< boost::winapi::ULONG_ >(STATUS_NO_SUCH_FILE): | |
109 | return boost::winapi::ERROR_FILE_NOT_FOUND_; | |
110 | case static_cast< boost::winapi::ULONG_ >(STATUS_ACCESS_DENIED): | |
111 | return boost::winapi::ERROR_ACCESS_DENIED_; | |
112 | // map "invalid info class" to "not supported" as this error likely indicates that the kernel does not support what we request | |
113 | case static_cast< boost::winapi::ULONG_ >(STATUS_INVALID_INFO_CLASS): | |
114 | default: | |
115 | return boost::winapi::ERROR_NOT_SUPPORTED_; | |
116 | } | |
117 | } | |
118 | ||
92f5a8d4 TL |
119 | #endif |
120 | ||
121 | // error handling helpers ----------------------------------------------------------// | |
122 | ||
123 | // Implemented in exception.cpp | |
124 | void emit_error(err_t error_num, system::error_code* ec, const char* message); | |
1e59de90 TL |
125 | void emit_error(err_t error_num, path const& p, system::error_code* ec, const char* message); |
126 | void emit_error(err_t error_num, path const& p1, path const& p2, system::error_code* ec, const char* message); | |
92f5a8d4 TL |
127 | |
128 | inline bool error(err_t error_num, system::error_code* ec, const char* message) | |
129 | { | |
1e59de90 TL |
130 | if (BOOST_LIKELY(!error_num)) |
131 | { | |
132 | if (ec) | |
133 | ec->clear(); | |
134 | return false; | |
135 | } | |
136 | else | |
137 | { // error | |
138 | filesystem::emit_error(error_num, ec, message); | |
139 | return true; | |
140 | } | |
92f5a8d4 TL |
141 | } |
142 | ||
1e59de90 | 143 | inline bool error(err_t error_num, path const& p, system::error_code* ec, const char* message) |
92f5a8d4 | 144 | { |
1e59de90 TL |
145 | if (BOOST_LIKELY(!error_num)) |
146 | { | |
147 | if (ec) | |
148 | ec->clear(); | |
149 | return false; | |
150 | } | |
151 | else | |
152 | { // error | |
153 | filesystem::emit_error(error_num, p, ec, message); | |
154 | return true; | |
155 | } | |
92f5a8d4 TL |
156 | } |
157 | ||
1e59de90 | 158 | inline bool error(err_t error_num, path const& p1, path const& p2, system::error_code* ec, const char* message) |
92f5a8d4 | 159 | { |
1e59de90 TL |
160 | if (BOOST_LIKELY(!error_num)) |
161 | { | |
162 | if (ec) | |
163 | ec->clear(); | |
164 | return false; | |
165 | } | |
166 | else | |
167 | { // error | |
168 | filesystem::emit_error(error_num, p1, p2, ec, message); | |
169 | return true; | |
170 | } | |
92f5a8d4 TL |
171 | } |
172 | ||
173 | } // namespace filesystem | |
174 | } // namespace boost | |
175 | ||
1e59de90 | 176 | #endif // BOOST_FILESYSTEM_SRC_ERROR_HANDLING_HPP_ |