Path: blob/main/contrib/llvm-project/libcxx/src/filesystem/error.h
35231 views
//===----------------------------------------------------------------------===////1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===////78#ifndef FILESYSTEM_ERROR_H9#define FILESYSTEM_ERROR_H1011#include <__assert>12#include <__config>13#include <cerrno>14#include <cstdarg>15#include <cstddef>16#include <cstdint>17#include <filesystem>18#include <string>19#include <system_error>20#include <utility> // __libcpp_unreachable2122#include "format_string.h"2324#if defined(_LIBCPP_WIN32API)25# define WIN32_LEAN_AND_MEAN26# define NOMINMAX27# include <windows.h> // ERROR_* macros28#endif2930_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM3132namespace detail {3334#if defined(_LIBCPP_WIN32API)3536inline errc __win_err_to_errc(int err) {37constexpr struct {38DWORD win;39errc errc;40} win_error_mapping[] = {41{ERROR_ACCESS_DENIED, errc::permission_denied},42{ERROR_ALREADY_EXISTS, errc::file_exists},43{ERROR_BAD_NETPATH, errc::no_such_file_or_directory},44{ERROR_BAD_PATHNAME, errc::no_such_file_or_directory},45{ERROR_BAD_UNIT, errc::no_such_device},46{ERROR_BROKEN_PIPE, errc::broken_pipe},47{ERROR_BUFFER_OVERFLOW, errc::filename_too_long},48{ERROR_BUSY, errc::device_or_resource_busy},49{ERROR_BUSY_DRIVE, errc::device_or_resource_busy},50{ERROR_CANNOT_MAKE, errc::permission_denied},51{ERROR_CANTOPEN, errc::io_error},52{ERROR_CANTREAD, errc::io_error},53{ERROR_CANTWRITE, errc::io_error},54{ERROR_CURRENT_DIRECTORY, errc::permission_denied},55{ERROR_DEV_NOT_EXIST, errc::no_such_device},56{ERROR_DEVICE_IN_USE, errc::device_or_resource_busy},57{ERROR_DIR_NOT_EMPTY, errc::directory_not_empty},58{ERROR_DIRECTORY, errc::invalid_argument},59{ERROR_DISK_FULL, errc::no_space_on_device},60{ERROR_FILE_EXISTS, errc::file_exists},61{ERROR_FILE_NOT_FOUND, errc::no_such_file_or_directory},62{ERROR_HANDLE_DISK_FULL, errc::no_space_on_device},63{ERROR_INVALID_ACCESS, errc::permission_denied},64{ERROR_INVALID_DRIVE, errc::no_such_device},65{ERROR_INVALID_FUNCTION, errc::function_not_supported},66{ERROR_INVALID_HANDLE, errc::invalid_argument},67{ERROR_INVALID_NAME, errc::no_such_file_or_directory},68{ERROR_INVALID_PARAMETER, errc::invalid_argument},69{ERROR_LOCK_VIOLATION, errc::no_lock_available},70{ERROR_LOCKED, errc::no_lock_available},71{ERROR_NEGATIVE_SEEK, errc::invalid_argument},72{ERROR_NOACCESS, errc::permission_denied},73{ERROR_NOT_ENOUGH_MEMORY, errc::not_enough_memory},74{ERROR_NOT_READY, errc::resource_unavailable_try_again},75{ERROR_NOT_SAME_DEVICE, errc::cross_device_link},76{ERROR_NOT_SUPPORTED, errc::not_supported},77{ERROR_OPEN_FAILED, errc::io_error},78{ERROR_OPEN_FILES, errc::device_or_resource_busy},79{ERROR_OPERATION_ABORTED, errc::operation_canceled},80{ERROR_OUTOFMEMORY, errc::not_enough_memory},81{ERROR_PATH_NOT_FOUND, errc::no_such_file_or_directory},82{ERROR_READ_FAULT, errc::io_error},83{ERROR_REPARSE_TAG_INVALID, errc::invalid_argument},84{ERROR_RETRY, errc::resource_unavailable_try_again},85{ERROR_SEEK, errc::io_error},86{ERROR_SHARING_VIOLATION, errc::permission_denied},87{ERROR_TOO_MANY_OPEN_FILES, errc::too_many_files_open},88{ERROR_WRITE_FAULT, errc::io_error},89{ERROR_WRITE_PROTECT, errc::permission_denied},90};9192for (const auto& pair : win_error_mapping)93if (pair.win == static_cast<DWORD>(err))94return pair.errc;95return errc::invalid_argument;96}9798#endif // _LIBCPP_WIN32API99100inline error_code capture_errno() {101_LIBCPP_ASSERT_INTERNAL(errno != 0, "Expected errno to be non-zero");102return error_code(errno, generic_category());103}104105#if defined(_LIBCPP_WIN32API)106inline error_code make_windows_error(int err) { return make_error_code(__win_err_to_errc(err)); }107#endif108109template <class T>110T error_value();111template <>112inline constexpr void error_value<void>() {}113template <>114inline bool error_value<bool>() {115return false;116}117#if __SIZEOF_SIZE_T__ != __SIZEOF_LONG_LONG__118template <>119inline size_t error_value<size_t>() {120return size_t(-1);121}122#endif123template <>124inline uintmax_t error_value<uintmax_t>() {125return uintmax_t(-1);126}127template <>128inline constexpr file_time_type error_value<file_time_type>() {129return file_time_type::min();130}131template <>132inline path error_value<path>() {133return {};134}135136template <class T>137struct ErrorHandler {138const char* func_name_;139error_code* ec_ = nullptr;140const path* p1_ = nullptr;141const path* p2_ = nullptr;142143ErrorHandler(const char* fname, error_code* ec, const path* p1 = nullptr, const path* p2 = nullptr)144: func_name_(fname), ec_(ec), p1_(p1), p2_(p2) {145if (ec_)146ec_->clear();147}148149T report(const error_code& ec) const {150if (ec_) {151*ec_ = ec;152return error_value<T>();153}154string what = string("in ") + func_name_;155switch (bool(p1_) + bool(p2_)) {156case 0:157__throw_filesystem_error(what, ec);158case 1:159__throw_filesystem_error(what, *p1_, ec);160case 2:161__throw_filesystem_error(what, *p1_, *p2_, ec);162}163__libcpp_unreachable();164}165166_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 0)167void report_impl(const error_code& ec, const char* msg, va_list ap) const {168if (ec_) {169*ec_ = ec;170return;171}172string what = string("in ") + func_name_ + ": " + detail::vformat_string(msg, ap);173switch (bool(p1_) + bool(p2_)) {174case 0:175__throw_filesystem_error(what, ec);176case 1:177__throw_filesystem_error(what, *p1_, ec);178case 2:179__throw_filesystem_error(what, *p1_, *p2_, ec);180}181__libcpp_unreachable();182}183184_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)185T report(const error_code& ec, const char* msg, ...) const {186va_list ap;187va_start(ap, msg);188#ifndef _LIBCPP_HAS_NO_EXCEPTIONS189try {190#endif // _LIBCPP_HAS_NO_EXCEPTIONS191report_impl(ec, msg, ap);192#ifndef _LIBCPP_HAS_NO_EXCEPTIONS193} catch (...) {194va_end(ap);195throw;196}197#endif // _LIBCPP_HAS_NO_EXCEPTIONS198va_end(ap);199return error_value<T>();200}201202T report(errc const& err) const { return report(make_error_code(err)); }203204_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4)205T report(errc const& err, const char* msg, ...) const {206va_list ap;207va_start(ap, msg);208#ifndef _LIBCPP_HAS_NO_EXCEPTIONS209try {210#endif // _LIBCPP_HAS_NO_EXCEPTIONS211report_impl(make_error_code(err), msg, ap);212#ifndef _LIBCPP_HAS_NO_EXCEPTIONS213} catch (...) {214va_end(ap);215throw;216}217#endif // _LIBCPP_HAS_NO_EXCEPTIONS218va_end(ap);219return error_value<T>();220}221222private:223ErrorHandler(ErrorHandler const&) = delete;224ErrorHandler& operator=(ErrorHandler const&) = delete;225};226227} // end namespace detail228229_LIBCPP_END_NAMESPACE_FILESYSTEM230231#endif // FILESYSTEM_ERROR_H232233234