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
13#ifndef BOOST_FILESYSTEM_SRC_ERROR_HANDLING_HPP_
14#define BOOST_FILESYSTEM_SRC_ERROR_HANDLING_HPP_
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#include <boost/filesystem/detail/header.hpp> // must be the last #include
28
29namespace boost {
30namespace filesystem {
31
32#if defined(BOOST_POSIX_API)
33
34typedef int err_t;
35
36// POSIX uses a 0 return to indicate success
37#define BOOST_ERRNO errno
38
39#define BOOST_ERROR_FILE_NOT_FOUND ENOENT
40#define BOOST_ERROR_ALREADY_EXISTS EEXIST
41#define BOOST_ERROR_NOT_SUPPORTED ENOSYS
42
43#else
44
45typedef boost::winapi::DWORD_ err_t;
46
47// Windows uses a non-0 return to indicate success
48#define BOOST_ERRNO boost::winapi::GetLastError()
49
50#define BOOST_ERROR_FILE_NOT_FOUND boost::winapi::ERROR_FILE_NOT_FOUND_
51#define BOOST_ERROR_ALREADY_EXISTS boost::winapi::ERROR_ALREADY_EXISTS_
52#define BOOST_ERROR_NOT_SUPPORTED boost::winapi::ERROR_NOT_SUPPORTED_
53
54// Note: Legacy MinGW doesn't have ntstatus.h and doesn't define NTSTATUS error codes other than STATUS_SUCCESS.
55#if !defined(NT_SUCCESS)
56#define NT_SUCCESS(Status) (((boost::winapi::NTSTATUS_)(Status)) >= 0)
57#endif
58#if !defined(STATUS_SUCCESS)
59#define STATUS_SUCCESS ((boost::winapi::NTSTATUS_)0x00000000l)
60#endif
61#if !defined(STATUS_NOT_IMPLEMENTED)
62#define STATUS_NOT_IMPLEMENTED ((boost::winapi::NTSTATUS_)0xC0000002l)
63#endif
64#if !defined(STATUS_INVALID_INFO_CLASS)
65#define STATUS_INVALID_INFO_CLASS ((boost::winapi::NTSTATUS_)0xC0000003l)
66#endif
67#if !defined(STATUS_INVALID_HANDLE)
68#define STATUS_INVALID_HANDLE ((boost::winapi::NTSTATUS_)0xC0000008l)
69#endif
70#if !defined(STATUS_INVALID_PARAMETER)
71#define STATUS_INVALID_PARAMETER ((boost::winapi::NTSTATUS_)0xC000000Dl)
72#endif
73#if !defined(STATUS_NO_SUCH_DEVICE)
74#define STATUS_NO_SUCH_DEVICE ((boost::winapi::NTSTATUS_)0xC000000El)
75#endif
76#if !defined(STATUS_NO_SUCH_FILE)
77#define STATUS_NO_SUCH_FILE ((boost::winapi::NTSTATUS_)0xC000000Fl)
78#endif
79#if !defined(STATUS_NO_MORE_FILES)
80#define STATUS_NO_MORE_FILES ((boost::winapi::NTSTATUS_)0x80000006l)
81#endif
82#if !defined(STATUS_BUFFER_OVERFLOW)
83#define STATUS_BUFFER_OVERFLOW ((boost::winapi::NTSTATUS_)0x80000005l)
84#endif
85#if !defined(STATUS_NO_MEMORY)
86#define STATUS_NO_MEMORY ((boost::winapi::NTSTATUS_)0xC0000017l)
87#endif
88#if !defined(STATUS_ACCESS_DENIED)
89#define STATUS_ACCESS_DENIED ((boost::winapi::NTSTATUS_)0xC0000022l)
90#endif
91#if !defined(STATUS_OBJECT_NAME_NOT_FOUND)
92#define STATUS_OBJECT_NAME_NOT_FOUND ((boost::winapi::NTSTATUS_)0xC0000034l)
93#endif
94#if !defined(STATUS_OBJECT_PATH_NOT_FOUND)
95#define STATUS_OBJECT_PATH_NOT_FOUND ((boost::winapi::NTSTATUS_)0xC000003Al)
96#endif
97#if !defined(STATUS_SHARING_VIOLATION)
98#define STATUS_SHARING_VIOLATION ((boost::winapi::NTSTATUS_)0xC0000043l)
99#endif
100#if !defined(STATUS_EAS_NOT_SUPPORTED)
101#define STATUS_EAS_NOT_SUPPORTED ((boost::winapi::NTSTATUS_)0xC000004Fl)
102#endif
103#if !defined(STATUS_NOT_SUPPORTED)
104#define STATUS_NOT_SUPPORTED ((boost::winapi::NTSTATUS_)0xC00000BBl)
105#endif
106#if !defined(STATUS_BAD_NETWORK_PATH)
107#define STATUS_BAD_NETWORK_PATH ((boost::winapi::NTSTATUS_)0xC00000BEl)
108#endif
109#if !defined(STATUS_DEVICE_DOES_NOT_EXIST)
110#define STATUS_DEVICE_DOES_NOT_EXIST ((boost::winapi::NTSTATUS_)0xC00000C0l)
111#endif
112#if !defined(STATUS_BAD_NETWORK_NAME)
113#define STATUS_BAD_NETWORK_NAME ((boost::winapi::NTSTATUS_)0xC00000CCl)
114#endif
115#if !defined(STATUS_DIRECTORY_NOT_EMPTY)
116#define STATUS_DIRECTORY_NOT_EMPTY ((boost::winapi::NTSTATUS_)0xC0000101l)
117#endif
118#if !defined(STATUS_NOT_A_DIRECTORY)
119#define STATUS_NOT_A_DIRECTORY ((boost::winapi::NTSTATUS_)0xC0000103l)
120#endif
121#if !defined(STATUS_NOT_FOUND)
122#define STATUS_NOT_FOUND ((boost::winapi::NTSTATUS_)0xC0000225l)
123#endif
124
125//! Converts NTSTATUS error codes to Win32 error codes for reporting
126inline boost::winapi::DWORD_ translate_ntstatus(boost::winapi::NTSTATUS_ status) noexcept
127{
128 // We have to cast to unsigned integral type to avoid signed overflow and narrowing conversion in the constants.
129 switch (static_cast< boost::winapi::ULONG_ >(status))
130 {
131 case static_cast< boost::winapi::ULONG_ >(STATUS_NO_MEMORY):
132 return boost::winapi::ERROR_OUTOFMEMORY_;
133 case static_cast< boost::winapi::ULONG_ >(STATUS_BUFFER_OVERFLOW):
134 return boost::winapi::ERROR_BUFFER_OVERFLOW_;
135 case static_cast< boost::winapi::ULONG_ >(STATUS_INVALID_HANDLE):
136 return boost::winapi::ERROR_INVALID_HANDLE_;
137 case static_cast< boost::winapi::ULONG_ >(STATUS_INVALID_PARAMETER):
138 return boost::winapi::ERROR_INVALID_PARAMETER_;
139 case static_cast< boost::winapi::ULONG_ >(STATUS_NO_MORE_FILES):
140 return boost::winapi::ERROR_NO_MORE_FILES_;
141 case static_cast< boost::winapi::ULONG_ >(STATUS_NO_SUCH_DEVICE):
142 case static_cast< boost::winapi::ULONG_ >(STATUS_DEVICE_DOES_NOT_EXIST):
143 return boost::winapi::ERROR_DEV_NOT_EXIST_;
144 case static_cast< boost::winapi::ULONG_ >(STATUS_NO_SUCH_FILE):
145 case static_cast< boost::winapi::ULONG_ >(STATUS_OBJECT_NAME_NOT_FOUND):
146 case static_cast< boost::winapi::ULONG_ >(STATUS_OBJECT_PATH_NOT_FOUND):
147 return boost::winapi::ERROR_FILE_NOT_FOUND_;
148 case static_cast< boost::winapi::ULONG_ >(STATUS_SHARING_VIOLATION):
149 return boost::winapi::ERROR_SHARING_VIOLATION_;
150 case static_cast< boost::winapi::ULONG_ >(STATUS_EAS_NOT_SUPPORTED):
151 return boost::winapi::ERROR_EAS_NOT_SUPPORTED_;
152 case static_cast< boost::winapi::ULONG_ >(STATUS_ACCESS_DENIED):
153 return boost::winapi::ERROR_ACCESS_DENIED_;
154 case static_cast< boost::winapi::ULONG_ >(STATUS_BAD_NETWORK_PATH):
155 return boost::winapi::ERROR_BAD_NETPATH_;
156 case static_cast< boost::winapi::ULONG_ >(STATUS_BAD_NETWORK_NAME):
157 return boost::winapi::ERROR_BAD_NET_NAME_;
158 case static_cast< boost::winapi::ULONG_ >(STATUS_DIRECTORY_NOT_EMPTY):
159 return boost::winapi::ERROR_DIR_NOT_EMPTY_;
160 case static_cast< boost::winapi::ULONG_ >(STATUS_NOT_A_DIRECTORY):
161 return boost::winapi::ERROR_DIRECTORY_; // The directory name is invalid
162 case static_cast< boost::winapi::ULONG_ >(STATUS_NOT_FOUND):
163 return boost::winapi::ERROR_NOT_FOUND_;
164 // map "invalid info class" to "not supported" as this error likely indicates that the kernel does not support what we request
165 case static_cast< boost::winapi::ULONG_ >(STATUS_INVALID_INFO_CLASS):
166 default:
167 return boost::winapi::ERROR_NOT_SUPPORTED_;
168 }
169}
170
171//! Tests if the NTSTATUS indicates that the file is not found
172inline bool not_found_ntstatus(boost::winapi::NTSTATUS_ status) noexcept
173{
174 return status == STATUS_NO_SUCH_FILE || status == STATUS_OBJECT_NAME_NOT_FOUND || status == STATUS_OBJECT_PATH_NOT_FOUND ||
175 status == STATUS_BAD_NETWORK_PATH || status == STATUS_BAD_NETWORK_NAME;
176}
177
178#endif
179
180// error handling helpers ----------------------------------------------------------//
181
182// Implemented in exception.cpp
183void emit_error(err_t error_num, system::error_code* ec, const char* message);
184void emit_error(err_t error_num, path const& p, system::error_code* ec, const char* message);
185void emit_error(err_t error_num, path const& p1, path const& p2, system::error_code* ec, const char* message);
186
187inline bool error(err_t error_num, system::error_code* ec, const char* message)
188{
189 if (BOOST_LIKELY(!error_num))
190 {
191 if (ec)
192 ec->clear();
193 return false;
194 }
195 else
196 { // error
197 filesystem::emit_error(error_num, ec, message);
198 return true;
199 }
200}
201
202inline bool error(err_t error_num, path const& p, system::error_code* ec, const char* message)
203{
204 if (BOOST_LIKELY(!error_num))
205 {
206 if (ec)
207 ec->clear();
208 return false;
209 }
210 else
211 { // error
212 filesystem::emit_error(error_num, p, ec, message);
213 return true;
214 }
215}
216
217inline bool error(err_t error_num, path const& p1, path const& p2, system::error_code* ec, const char* message)
218{
219 if (BOOST_LIKELY(!error_num))
220 {
221 if (ec)
222 ec->clear();
223 return false;
224 }
225 else
226 { // error
227 filesystem::emit_error(error_num, p1, p2, ec, message);
228 return true;
229 }
230}
231
232} // namespace filesystem
233} // namespace boost
234
235#include <boost/filesystem/detail/footer.hpp>
236
237#endif // BOOST_FILESYSTEM_SRC_ERROR_HANDLING_HPP_
238

source code of boost/libs/filesystem/src/error_handling.hpp