Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/libcxx/src/filesystem/error.h
35231 views
1
//===----------------------------------------------------------------------===////
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===////
8
9
#ifndef FILESYSTEM_ERROR_H
10
#define FILESYSTEM_ERROR_H
11
12
#include <__assert>
13
#include <__config>
14
#include <cerrno>
15
#include <cstdarg>
16
#include <cstddef>
17
#include <cstdint>
18
#include <filesystem>
19
#include <string>
20
#include <system_error>
21
#include <utility> // __libcpp_unreachable
22
23
#include "format_string.h"
24
25
#if defined(_LIBCPP_WIN32API)
26
# define WIN32_LEAN_AND_MEAN
27
# define NOMINMAX
28
# include <windows.h> // ERROR_* macros
29
#endif
30
31
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
32
33
namespace detail {
34
35
#if defined(_LIBCPP_WIN32API)
36
37
inline errc __win_err_to_errc(int err) {
38
constexpr struct {
39
DWORD win;
40
errc errc;
41
} win_error_mapping[] = {
42
{ERROR_ACCESS_DENIED, errc::permission_denied},
43
{ERROR_ALREADY_EXISTS, errc::file_exists},
44
{ERROR_BAD_NETPATH, errc::no_such_file_or_directory},
45
{ERROR_BAD_PATHNAME, errc::no_such_file_or_directory},
46
{ERROR_BAD_UNIT, errc::no_such_device},
47
{ERROR_BROKEN_PIPE, errc::broken_pipe},
48
{ERROR_BUFFER_OVERFLOW, errc::filename_too_long},
49
{ERROR_BUSY, errc::device_or_resource_busy},
50
{ERROR_BUSY_DRIVE, errc::device_or_resource_busy},
51
{ERROR_CANNOT_MAKE, errc::permission_denied},
52
{ERROR_CANTOPEN, errc::io_error},
53
{ERROR_CANTREAD, errc::io_error},
54
{ERROR_CANTWRITE, errc::io_error},
55
{ERROR_CURRENT_DIRECTORY, errc::permission_denied},
56
{ERROR_DEV_NOT_EXIST, errc::no_such_device},
57
{ERROR_DEVICE_IN_USE, errc::device_or_resource_busy},
58
{ERROR_DIR_NOT_EMPTY, errc::directory_not_empty},
59
{ERROR_DIRECTORY, errc::invalid_argument},
60
{ERROR_DISK_FULL, errc::no_space_on_device},
61
{ERROR_FILE_EXISTS, errc::file_exists},
62
{ERROR_FILE_NOT_FOUND, errc::no_such_file_or_directory},
63
{ERROR_HANDLE_DISK_FULL, errc::no_space_on_device},
64
{ERROR_INVALID_ACCESS, errc::permission_denied},
65
{ERROR_INVALID_DRIVE, errc::no_such_device},
66
{ERROR_INVALID_FUNCTION, errc::function_not_supported},
67
{ERROR_INVALID_HANDLE, errc::invalid_argument},
68
{ERROR_INVALID_NAME, errc::no_such_file_or_directory},
69
{ERROR_INVALID_PARAMETER, errc::invalid_argument},
70
{ERROR_LOCK_VIOLATION, errc::no_lock_available},
71
{ERROR_LOCKED, errc::no_lock_available},
72
{ERROR_NEGATIVE_SEEK, errc::invalid_argument},
73
{ERROR_NOACCESS, errc::permission_denied},
74
{ERROR_NOT_ENOUGH_MEMORY, errc::not_enough_memory},
75
{ERROR_NOT_READY, errc::resource_unavailable_try_again},
76
{ERROR_NOT_SAME_DEVICE, errc::cross_device_link},
77
{ERROR_NOT_SUPPORTED, errc::not_supported},
78
{ERROR_OPEN_FAILED, errc::io_error},
79
{ERROR_OPEN_FILES, errc::device_or_resource_busy},
80
{ERROR_OPERATION_ABORTED, errc::operation_canceled},
81
{ERROR_OUTOFMEMORY, errc::not_enough_memory},
82
{ERROR_PATH_NOT_FOUND, errc::no_such_file_or_directory},
83
{ERROR_READ_FAULT, errc::io_error},
84
{ERROR_REPARSE_TAG_INVALID, errc::invalid_argument},
85
{ERROR_RETRY, errc::resource_unavailable_try_again},
86
{ERROR_SEEK, errc::io_error},
87
{ERROR_SHARING_VIOLATION, errc::permission_denied},
88
{ERROR_TOO_MANY_OPEN_FILES, errc::too_many_files_open},
89
{ERROR_WRITE_FAULT, errc::io_error},
90
{ERROR_WRITE_PROTECT, errc::permission_denied},
91
};
92
93
for (const auto& pair : win_error_mapping)
94
if (pair.win == static_cast<DWORD>(err))
95
return pair.errc;
96
return errc::invalid_argument;
97
}
98
99
#endif // _LIBCPP_WIN32API
100
101
inline error_code capture_errno() {
102
_LIBCPP_ASSERT_INTERNAL(errno != 0, "Expected errno to be non-zero");
103
return error_code(errno, generic_category());
104
}
105
106
#if defined(_LIBCPP_WIN32API)
107
inline error_code make_windows_error(int err) { return make_error_code(__win_err_to_errc(err)); }
108
#endif
109
110
template <class T>
111
T error_value();
112
template <>
113
inline constexpr void error_value<void>() {}
114
template <>
115
inline bool error_value<bool>() {
116
return false;
117
}
118
#if __SIZEOF_SIZE_T__ != __SIZEOF_LONG_LONG__
119
template <>
120
inline size_t error_value<size_t>() {
121
return size_t(-1);
122
}
123
#endif
124
template <>
125
inline uintmax_t error_value<uintmax_t>() {
126
return uintmax_t(-1);
127
}
128
template <>
129
inline constexpr file_time_type error_value<file_time_type>() {
130
return file_time_type::min();
131
}
132
template <>
133
inline path error_value<path>() {
134
return {};
135
}
136
137
template <class T>
138
struct ErrorHandler {
139
const char* func_name_;
140
error_code* ec_ = nullptr;
141
const path* p1_ = nullptr;
142
const path* p2_ = nullptr;
143
144
ErrorHandler(const char* fname, error_code* ec, const path* p1 = nullptr, const path* p2 = nullptr)
145
: func_name_(fname), ec_(ec), p1_(p1), p2_(p2) {
146
if (ec_)
147
ec_->clear();
148
}
149
150
T report(const error_code& ec) const {
151
if (ec_) {
152
*ec_ = ec;
153
return error_value<T>();
154
}
155
string what = string("in ") + func_name_;
156
switch (bool(p1_) + bool(p2_)) {
157
case 0:
158
__throw_filesystem_error(what, ec);
159
case 1:
160
__throw_filesystem_error(what, *p1_, ec);
161
case 2:
162
__throw_filesystem_error(what, *p1_, *p2_, ec);
163
}
164
__libcpp_unreachable();
165
}
166
167
_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 0)
168
void report_impl(const error_code& ec, const char* msg, va_list ap) const {
169
if (ec_) {
170
*ec_ = ec;
171
return;
172
}
173
string what = string("in ") + func_name_ + ": " + detail::vformat_string(msg, ap);
174
switch (bool(p1_) + bool(p2_)) {
175
case 0:
176
__throw_filesystem_error(what, ec);
177
case 1:
178
__throw_filesystem_error(what, *p1_, ec);
179
case 2:
180
__throw_filesystem_error(what, *p1_, *p2_, ec);
181
}
182
__libcpp_unreachable();
183
}
184
185
_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
186
T report(const error_code& ec, const char* msg, ...) const {
187
va_list ap;
188
va_start(ap, msg);
189
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
190
try {
191
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
192
report_impl(ec, msg, ap);
193
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
194
} catch (...) {
195
va_end(ap);
196
throw;
197
}
198
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
199
va_end(ap);
200
return error_value<T>();
201
}
202
203
T report(errc const& err) const { return report(make_error_code(err)); }
204
205
_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)
206
T report(errc const& err, const char* msg, ...) const {
207
va_list ap;
208
va_start(ap, msg);
209
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
210
try {
211
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
212
report_impl(make_error_code(err), msg, ap);
213
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
214
} catch (...) {
215
va_end(ap);
216
throw;
217
}
218
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
219
va_end(ap);
220
return error_value<T>();
221
}
222
223
private:
224
ErrorHandler(ErrorHandler const&) = delete;
225
ErrorHandler& operator=(ErrorHandler const&) = delete;
226
};
227
228
} // end namespace detail
229
230
_LIBCPP_END_NAMESPACE_FILESYSTEM
231
232
#endif // FILESYSTEM_ERROR_H
233
234