diff options
-rw-r--r-- | include/afio/revision.hpp | 6 | ||||
-rw-r--r-- | include/afio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp | 6 | ||||
-rw-r--r-- | include/afio/v2.0/config.hpp | 157 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/cached_parent_handle_adapter.ipp | 2 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/path_discovery.ipp | 4 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/posix/io_handle.ipp | 2 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/posix/path_discovery.ipp | 2 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/storage_profile.ipp | 44 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/windows/fs_handle.ipp | 2 | ||||
-rw-r--r-- | include/afio/v2.0/detail/impl/windows/path_view.ipp | 5 | ||||
-rw-r--r-- | include/afio/v2.0/handle.hpp | 62 | ||||
-rw-r--r-- | include/afio/v2.0/stat.hpp | 2 | ||||
-rw-r--r-- | include/afio/v2.0/statfs.hpp | 2 | ||||
-rw-r--r-- | include/afio/v2.0/storage_profile.hpp | 7 | ||||
-rw-r--r-- | test/tests/current_path.cpp | 10 | ||||
-rw-r--r-- | test/tests/directory_handle_create_close/runner.cpp | 4 |
16 files changed, 216 insertions, 101 deletions
diff --git a/include/afio/revision.hpp b/include/afio/revision.hpp index 6cc12e15..0f8100d6 100644 --- a/include/afio/revision.hpp +++ b/include/afio/revision.hpp @@ -1,4 +1,4 @@ // Note the second line of this file must ALWAYS be the git SHA, third line ALWAYS the git SHA update time -#define AFIO_PREVIOUS_COMMIT_REF adce05d59baf2f063244a02efe26f6c7ad9865a2 -#define AFIO_PREVIOUS_COMMIT_DATE "2018-05-31 08:10:02 +00:00" -#define AFIO_PREVIOUS_COMMIT_UNIQUE adce05d5 +#define AFIO_PREVIOUS_COMMIT_REF 9d2321f2d4ea7076159d984fcf734a415cc9bdd1 +#define AFIO_PREVIOUS_COMMIT_DATE "2018-06-01 18:39:21 +00:00" +#define AFIO_PREVIOUS_COMMIT_UNIQUE 9d2321f2 diff --git a/include/afio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp b/include/afio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp index 75ccde59..901ae528 100644 --- a/include/afio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp +++ b/include/afio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp @@ -162,7 +162,7 @@ namespace algorithm if(!o2) { AFIO_LOG_FATAL(0, "memory_map::~memory_map() truncate failed"); - std::cerr << "~memory_map() truncate failed due to " << o2.error().message() << std::endl; + std::cerr << "~memory_map() truncate failed due to " << o2.error().message().c_str() << std::endl; abort(); } // Unlink the temp file. We don't trap any failure to unlink on FreeBSD it can forget current path. @@ -170,10 +170,10 @@ namespace algorithm if(!o3) { #ifdef __FreeBSD__ - std::cerr << "~memory_map() unlink failed due to " << o3.error().message() << std::endl; + std::cerr << "~memory_map() unlink failed due to " << o3.error().message().c_str() << std::endl; #else AFIO_LOG_FATAL(0, "memory_map::~memory_map() unlink failed"); - std::cerr << "~memory_map() unlink failed due to " << o3.error().message() << std::endl; + std::cerr << "~memory_map() unlink failed due to " << o3.error().message().c_str() << std::endl; abort(); #endif } diff --git a/include/afio/v2.0/config.hpp b/include/afio/v2.0/config.hpp index 6f4bfe25..8ebbdb27 100644 --- a/include/afio/v2.0/config.hpp +++ b/include/afio/v2.0/config.hpp @@ -390,17 +390,26 @@ namespace detail template <class T> struct error_domain_value_type { //! \brief The type of code - T ec; + T sc{}; // The id of the thread where this failure occurred - uint32_t thread_id{0}; + uint32_t _thread_id{0}; // The TLS path store entry - uint16_t tls_path_id1{static_cast<uint16_t>(-1)}, _tls_path_id2{static_cast<uint16_t>(-1)}; + uint16_t _tls_path_id1{static_cast<uint16_t>(-1)}, _tls_path_id2{static_cast<uint16_t>(-1)}; // The id of the relevant log entry in the AFIO log (if logging enabled) - size_t log_id{static_cast<size_t>(-1)}; + size_t _log_id{static_cast<size_t>(-1)}; - //! Implicitly constructs an instance. Defined in handle.hpp as we need to understand handle. - inline error_domain_value_type(T _sc); // NOLINT + //! Default construction + error_domain_value_type() = default; + + //! Implicitly constructs an instance + constexpr inline error_domain_value_type(T _sc) + : sc(_sc) + { + } // NOLINT + + //! Compares to a T + constexpr bool operator==(const T &b) const noexcept { return sc == b; } }; } @@ -409,6 +418,7 @@ namespace detail */ template <class BaseStatusCodeDomain> class error_domain : public BaseStatusCodeDomain { + friend class SYSTEM_ERROR2_NAMESPACE::status_code<error_domain>; using _base = BaseStatusCodeDomain; public: @@ -450,28 +460,90 @@ using OUTCOME_V2_NAMESPACE::in_place_type; using SYSTEM_ERROR2_NAMESPACE::errc; //! Helper for constructing an error code from an errc -inline error_code generic_error(errc c) -{ - return SYSTEM_ERROR2_NAMESPACE::status_code<error_domain<SYSTEM_ERROR2_NAMESPACE::generic_code::domain_type>>(c); -} +inline error_code generic_error(errc c); #ifndef _WIN32 //! Helper for constructing an error code from a POSIX errno -inline error_code posix_error(int c = errno) -{ - return SYSTEM_ERROR2_NAMESPACE::status_code<error_domain<SYSTEM_ERROR2_NAMESPACE::posix_code::domain_type>>(c); -} +inline error_code posix_error(int c = errno); #else //! Helper for constructing an error code from a DWORD -inline error_code win32_error(SYSTEM_ERROR2_NAMESPACE::win32::DWORD c = SYSTEM_ERROR2_NAMESPACE::win32::GetLastError()) +inline error_code win32_error(SYSTEM_ERROR2_NAMESPACE::win32::DWORD c = SYSTEM_ERROR2_NAMESPACE::win32::GetLastError()); +//! Helper for constructing an error code from a NTSTATUS +inline error_code ntkernel_error(SYSTEM_ERROR2_NAMESPACE::win32::NTSTATUS c); +#endif + +namespace detail { - return SYSTEM_ERROR2_NAMESPACE::status_code<error_domain<SYSTEM_ERROR2_NAMESPACE::win32_code::domain_type>>(c); + inline std::ostream &operator<<(std::ostream &s, const error_code &v) { return s << "afio::error_code(" << v.message().c_str() << ")"; } } -//! Helper for constructing an error code from a NTSTATUS -inline error_code ntkernel_error(SYSTEM_ERROR2_NAMESPACE::win32::NTSTATUS c) +inline error_code error_from_exception(std::exception_ptr &&ep = std::current_exception(), error_code not_matched = generic_error(errc::resource_unavailable_try_again)) noexcept { - return SYSTEM_ERROR2_NAMESPACE::status_code<error_domain<SYSTEM_ERROR2_NAMESPACE::nt_code::domain_type>>(c); + if(!ep) + { + return generic_error(errc::success); + } + try + { + std::rethrow_exception(ep); + } + catch(const std::invalid_argument & /*unused*/) + { + ep = std::exception_ptr(); + return generic_error(errc::invalid_argument); + } + catch(const std::domain_error & /*unused*/) + { + ep = std::exception_ptr(); + return generic_error(errc::argument_out_of_domain); + } + catch(const std::length_error & /*unused*/) + { + ep = std::exception_ptr(); + return generic_error(errc::argument_list_too_long); + } + catch(const std::out_of_range & /*unused*/) + { + ep = std::exception_ptr(); + return generic_error(errc::result_out_of_range); + } + catch(const std::logic_error & /*unused*/) /* base class for this group */ + { + ep = std::exception_ptr(); + return generic_error(errc::invalid_argument); + } + catch(const std::system_error &e) /* also catches ios::failure */ + { + ep = std::exception_ptr(); + if(e.code().category() == std::generic_category()) + { + return generic_error(static_cast<errc>(static_cast<int>(e.code().value()))); + } + // Don't know this error code category, so fall through + } + catch(const std::overflow_error & /*unused*/) + { + ep = std::exception_ptr(); + return generic_error(errc::value_too_large); + } + catch(const std::range_error & /*unused*/) + { + ep = std::exception_ptr(); + return generic_error(errc::result_out_of_range); + } + catch(const std::runtime_error & /*unused*/) /* base class for this group */ + { + ep = std::exception_ptr(); + return generic_error(errc::resource_unavailable_try_again); + } + catch(const std::bad_alloc & /*unused*/) + { + ep = std::exception_ptr(); + return generic_error(errc::not_enough_memory); + } + catch(...) + { + } + return not_matched; } -#endif AFIO_V2_NAMESPACE_END @@ -487,22 +559,26 @@ AFIO_V2_NAMESPACE_BEGIN namespace detail { template <class Src> inline void append_path_info(Src &src, std::string &ret); - template <class Src> inline void fill_failure_info(Src &src); + template <class Dest, class Src> inline void fill_failure_info(Dest &dest, const Src &src); } +struct error_info; +inline std::error_code make_error_code(error_info ei); + /*! \struct error_info \brief The cause of the failure of an operation in AFIO. */ struct error_info { + friend inline std::error_code make_error_code(error_info ei); template <class Src> friend inline void detail::append_path_info(Src &src, std::string &ret); - template <class Src> friend inline void detail::fill_failure_info(Src &src); + template <class Dest, class Src> friend inline void detail::fill_failure_info(Dest &dest, const Src &src); - //! The error code for the failure +private: + // The error code for the failure std::error_code ec; #ifndef AFIO_DISABLE_PATHS_IN_FAILURE_INFO -private: // The id of the thread where this failure occurred uint32_t _thread_id{0}; // The TLS path store entry @@ -528,6 +604,8 @@ public: { } + //! Retrieve the value of the error code + int value() const noexcept { return ec.value(); } //! Retrieve any first path associated with this failure. Note this only works if called from the same thread as where the failure occurred. inline filesystem::path path1() const; //! Retrieve any second path associated with this failure. Note this only works if called from the same thread as where the failure occurred. @@ -538,39 +616,39 @@ public: C++ exception types e.g. `bad_alloc`, we throw those types using the string from `message()` where possible. We then will throw an `error` exception type. */ - inline void throw_as_exception() const; + inline void throw_exception() const; }; inline bool operator==(const error_info &a, const error_info &b) { - return a.ec == b.ec; + return make_error_code(a) == make_error_code(b); } inline bool operator!=(const error_info &a, const error_info &b) { - return a.ec != b.ec; + return make_error_code(a) != make_error_code(b); } OUTCOME_TEMPLATE(class ErrorCondEnum) OUTCOME_TREQUIRES(OUTCOME_TPRED(std::is_error_condition_enum<ErrorCondEnum>::value)) inline bool operator==(const error_info &a, const ErrorCondEnum &b) { - return a.ec == std::error_condition(b); + return make_error_code(a) == std::error_condition(b); } OUTCOME_TEMPLATE(class ErrorCondEnum) OUTCOME_TREQUIRES(OUTCOME_TPRED(std::is_error_condition_enum<ErrorCondEnum>::value)) inline bool operator==(const ErrorCondEnum &a, const error_info &b) { - return std::error_condition(a) == b.ec; + return std::error_condition(a) == make_error_code(b); } OUTCOME_TEMPLATE(class ErrorCondEnum) OUTCOME_TREQUIRES(OUTCOME_TPRED(std::is_error_condition_enum<ErrorCondEnum>::value)) inline bool operator!=(const error_info &a, const ErrorCondEnum &b) { - return a.ec != std::error_condition(b); + return make_error_code(a) != std::error_condition(b); } OUTCOME_TEMPLATE(class ErrorCondEnum) OUTCOME_TREQUIRES(OUTCOME_TPRED(std::is_error_condition_enum<ErrorCondEnum>::value)) inline bool operator!=(const ErrorCondEnum &a, const error_info &b) { - return std::error_condition(a) != b.ec; + return std::error_condition(a) != make_error_code(b); } #ifndef NDEBUG // Is trivial in all ways, except default constructibility @@ -578,7 +656,7 @@ static_assert(std::is_trivially_copyable<error_info>::value, "error_info is not #endif inline std::ostream &operator<<(std::ostream &s, const error_info &v) { - if(v.ec) + if(make_error_code(v)) { return s << "afio::error_info(" << v.message() << ")"; } @@ -589,10 +667,10 @@ inline std::error_code make_error_code(error_info ei) { return ei.ec; } -// Tell Outcome to call error_info::throw_as_exception() on no-value observation +// Tell Outcome to call error_info::throw_exception() on no-value observation inline void outcome_throw_as_system_error_with_payload(const error_info &ei) { - ei.throw_as_exception(); + ei.throw_exception(); } /*! \class error @@ -605,13 +683,13 @@ public: //! Constructs from an error_info explicit error(error_info _ei) - : filesystem::filesystem_error(_ei.message(), _ei.path1(), _ei.path2(), _ei.ec) + : filesystem::filesystem_error(_ei.message(), _ei.path1(), _ei.path2(), make_error_code(_ei)) , ei(_ei) { } }; -inline void error_info::throw_as_exception() const +inline void error_info::throw_exception() const { std::string msg; try @@ -965,10 +1043,9 @@ namespace detail template <class BaseStatusCodeDomain> inline typename error_domain<BaseStatusCodeDomain>::string_ref error_domain<BaseStatusCodeDomain>::_message(const SYSTEM_ERROR2_NAMESPACE::status_code<void> &code) const noexcept // NOLINT { assert(code.domain() == *this); - const auto &c = static_cast<const SYSTEM_ERROR2_NAMESPACE::status_code<error_domain> &>(code); // NOLINT - auto v = c.value(); - std::string ret = v.sc.message(); - detail::append_path_info(v, ret); + const auto &v = static_cast<const SYSTEM_ERROR2_NAMESPACE::status_code<error_domain> &>(code); // NOLINT + std::string ret = v.message().c_str(); + detail::append_path_info(v.value(), ret); return atomic_refcounted_string_ref(ret.c_str(), ret.size()); } #endif diff --git a/include/afio/v2.0/detail/impl/cached_parent_handle_adapter.ipp b/include/afio/v2.0/detail/impl/cached_parent_handle_adapter.ipp index 8cb3456f..bb2d0fbe 100644 --- a/include/afio/v2.0/detail/impl/cached_parent_handle_adapter.ipp +++ b/include/afio/v2.0/detail/impl/cached_parent_handle_adapter.ipp @@ -54,7 +54,7 @@ namespace algorithm if(!ret) { std::string msg("cached_path_handle::current_path() failed to retrieve current path of cached handle due to "); - msg.append(ret.error().message()); + msg.append(ret.error().message().c_str()); AFIO_LOG_WARN(nullptr, msg.c_str()); } else if(!ret.value().empty() && ret.value() != _lastpath) diff --git a/include/afio/v2.0/detail/impl/path_discovery.ipp b/include/afio/v2.0/detail/impl/path_discovery.ipp index 647f787a..1fd3588f 100644 --- a/include/afio/v2.0/detail/impl/path_discovery.ipp +++ b/include/afio/v2.0/detail/impl/path_discovery.ipp @@ -161,7 +161,7 @@ namespace path_discovery std::string msg("path_discovery::verified_temporary_directories() failed to create a file in "); msg.append(ps._all[n].path.u8string()); msg.append(" due to "); - msg.append(_fh.error().message()); + msg.append(_fh.error().message().c_str()); AFIO_LOG_WARN(nullptr, msg.c_str()); #endif ps._all[n].h = {}; @@ -187,7 +187,7 @@ namespace path_discovery std::string msg("path_discovery::verified_temporary_directories() failed to statfs the temp directory "); msg.append(ps._all[n].path.u8string()); msg.append(" due to "); - msg.append(statfsres.error().message()); + msg.append(statfsres.error().message().c_str()); AFIO_LOG_WARN(nullptr, msg.c_str()); #endif ps.all[n].stat = {}; diff --git a/include/afio/v2.0/detail/impl/posix/io_handle.ipp b/include/afio/v2.0/detail/impl/posix/io_handle.ipp index c5326008..c33ec08a 100644 --- a/include/afio/v2.0/detail/impl/posix/io_handle.ipp +++ b/include/afio/v2.0/detail/impl/posix/io_handle.ipp @@ -306,7 +306,7 @@ void io_handle::unlock(io_handle::extent_type offset, io_handle::extent_type byt } if(failed) { - error_info ret(posix_error()); + auto ret(posix_error()); (void) ret; AFIO_LOG_FATAL(_v.fd, "io_handle::unlock() failed"); std::terminate(); diff --git a/include/afio/v2.0/detail/impl/posix/path_discovery.ipp b/include/afio/v2.0/detail/impl/posix/path_discovery.ipp index 1d630ba8..0d072a29 100644 --- a/include/afio/v2.0/detail/impl/posix/path_discovery.ipp +++ b/include/afio/v2.0/detail/impl/posix/path_discovery.ipp @@ -72,7 +72,7 @@ namespace path_discovery if(!_passwdh) { std::string msg("path_discovery::all_temporary_directories() failed to open /etc/passwd due to "); - msg.append(_passwdh.error().message()); + msg.append(_passwdh.error().message().c_str()); AFIO_LOG_WARN(nullptr, msg.c_str()); } else diff --git a/include/afio/v2.0/detail/impl/storage_profile.ipp b/include/afio/v2.0/detail/impl/storage_profile.ipp index d15cbfa2..b37305af 100644 --- a/include/afio/v2.0/detail/impl/storage_profile.ipp +++ b/include/afio/v2.0/detail/impl/storage_profile.ipp @@ -420,9 +420,9 @@ namespace storage_profile auto _h(srch.clone()); if(!_h) { - throw std::runtime_error("concurrency::atomic_rewrite_quantum: " // NOLINT - "Could not open work file due to " + - _h.error().message()); + throw std::runtime_error(std::string("concurrency::atomic_rewrite_quantum: " // NOLINT + "Could not open work file due to ") + + _h.error().message().c_str()); } file_handle h(std::move(_h.value())); std::vector<byte, utils::page_allocator<byte>> buffer(size, to_byte(no)); @@ -459,9 +459,9 @@ namespace storage_profile auto _h(srch.clone()); if(!_h) { - throw std::runtime_error("concurrency::atomic_rewrite_quantum: " // NOLINT - "Could not open work file due to " + - _h.error().message()); + throw std::runtime_error(std::string("concurrency::atomic_rewrite_quantum: " // NOLINT + "Could not open work file due to ") + + _h.error().message().c_str()); } file_handle h(std::move(_h.value())); std::vector<byte, utils::page_allocator<byte>> buffer(size, to_byte(0)), tocmp(size, to_byte(0)); @@ -564,10 +564,10 @@ namespace storage_profile auto _h(srch.clone()); if(!_h) { - throw std::runtime_error("concurrency::atomic_rewrite_" // NOLINT - "quantum: Could not open work file " - "due to " + - _h.error().message()); + throw std::runtime_error(std::string("concurrency::atomic_rewrite_" // NOLINT + "quantum: Could not open work file " + "due to ") + + _h.error().message().c_str()); } file_handle h(std::move(_h.value())); std::vector<byte, utils::page_allocator<byte>> buffer(size, to_byte(no)); @@ -604,10 +604,10 @@ namespace storage_profile auto _h(srch.clone()); if(!_h) { - throw std::runtime_error("concurrency::atomic_rewrite_" // NOLINT - "quantum: Could not open work file " - "due to " + - _h.error().message()); + throw std::runtime_error(std::string("concurrency::atomic_rewrite_" // NOLINT + "quantum: Could not open work file " + "due to ") + + _h.error().message().c_str()); } file_handle h(std::move(_h.value())); std::vector<byte, utils::page_allocator<byte>> buffer(size, to_byte(0)), tocmp(size, to_byte(0)); @@ -725,10 +725,10 @@ namespace storage_profile auto _h(srch.clone()); if(!_h) { - throw std::runtime_error("concurrency::atomic_rewrite_" // NOLINT - "offset_boundary: Could not open " - "work file due to " + - _h.error().message()); + throw std::runtime_error(std::string("concurrency::atomic_rewrite_" // NOLINT + "offset_boundary: Could not open " + "work file due to ") + + _h.error().message().c_str()); } file_handle h(std::move(_h.value())); std::vector<byte, utils::page_allocator<byte>> buffer(size, to_byte(no)); @@ -765,10 +765,10 @@ namespace storage_profile auto _h(srch.clone()); if(!_h) { - throw std::runtime_error("concurrency::atomic_rewrite_" // NOLINT - "offset_boundary: Could not open " - "work file due to " + - _h.error().message()); + throw std::runtime_error(std::string("concurrency::atomic_rewrite_" // NOLINT + "offset_boundary: Could not open " + "work file due to ") + + _h.error().message().c_str()); } file_handle h(std::move(_h.value())); std::vector<byte, utils::page_allocator<byte>> buffer(size, to_byte(0)), tocmp(size, to_byte(0)); diff --git a/include/afio/v2.0/detail/impl/windows/fs_handle.ipp b/include/afio/v2.0/detail/impl/windows/fs_handle.ipp index 9fbe385b..c3b47873 100644 --- a/include/afio/v2.0/detail/impl/windows/fs_handle.ipp +++ b/include/afio/v2.0/detail/impl/windows/fs_handle.ipp @@ -242,7 +242,7 @@ result<void> fs_handle::unlink(deadline d) noexcept { // If something else is using it, we may not be able to rename // This error also annoyingly appears if the file has delete on close set on it already - if(out.error().ec.value() == static_cast<int>(0xC0000043) /*STATUS_SHARING_VIOLATION*/) + if(out.error().value() == static_cast<int>(0xC0000043) /*STATUS_SHARING_VIOLATION*/) { AFIO_LOG_WARN(this, "Failed to rename entry to random name to simulate immediate unlinking due to STATUS_SHARING_VIOLATION, skipping"); } diff --git a/include/afio/v2.0/detail/impl/windows/path_view.ipp b/include/afio/v2.0/detail/impl/windows/path_view.ipp index 168545e7..7439a020 100644 --- a/include/afio/v2.0/detail/impl/windows/path_view.ipp +++ b/include/afio/v2.0/detail/impl/windows/path_view.ipp @@ -33,10 +33,9 @@ AFIO_HEADERS_ONLY_MEMFUNC_SPEC void path_view::c_str::_from_utf8(const path_view using namespace windows_nt_kernel; ULONG written = 0; NTSTATUS ntstat = RtlUTF8ToUnicodeN(_buffer, static_cast<ULONG>(sizeof(_buffer) - sizeof(wchar_t)), &written, view._state._utf8.data(), static_cast<ULONG>(view._state._utf8.size())); - std::error_code ec = ntkernel_error(ntstat).ec; - if(ec && ec.value() < 0) + if(ntstat < 0) { - AFIO_LOG_FATAL(ec.value(), ec.message().c_str()); + AFIO_LOG_FATAL(ntstat, ntkernel_error(ntstat).message().c_str()); abort(); } length = static_cast<uint16_t>(written / sizeof(wchar_t)); diff --git a/include/afio/v2.0/handle.hpp b/include/afio/v2.0/handle.hpp index cec27231..483272a2 100644 --- a/include/afio/v2.0/handle.hpp +++ b/include/afio/v2.0/handle.hpp @@ -424,7 +424,7 @@ template <class T> struct construct #ifndef AFIO_DISABLE_PATHS_IN_FAILURE_INFO namespace detail { - template <class Src> inline void fill_failure_info(Src &src) + template <class Dest, class Src> inline void fill_failure_info(Dest &dest, const Src &src) { auto &tls = detail::tls_errored_results(); if(!tls.reentering_self) @@ -441,22 +441,22 @@ namespace detail if(currentpath_) { auto currentpath = currentpath_.value().u8string(); - src._thread_id = tls.this_thread_id; + dest._thread_id = tls.this_thread_id; #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4996) // the function may be unsafe #endif - strncpy(tls.next(src._tls_path_id1), QUICKCPPLIB_NAMESPACE::ringbuffer_log::last190(currentpath), 190); + strncpy(tls.next(dest._tls_path_id1), QUICKCPPLIB_NAMESPACE::ringbuffer_log::last190(currentpath), 190); #ifdef _MSC_VER #pragma warning(pop) #endif - src._tls_path_id2 = src._tls_path_id1 - 17; // guaranteed invalid + dest._tls_path_id2 = dest._tls_path_id1 - 17; // guaranteed invalid } } #if AFIO_LOGGING_LEVEL >= 2 if(log().log_level() >= log_level::error) { - src._log_id = log().emplace_back(log_level::error, src.ec.message().c_str(), static_cast<uint32_t>(nativeh._init), tls.this_thread_id); + dest._log_id = log().emplace_back(log_level::error, src.message().c_str(), static_cast<uint32_t>(nativeh._init), tls.this_thread_id); } #endif } @@ -467,19 +467,51 @@ namespace detail #if AFIO_EXPERIMENTAL_STATUS_CODE #ifndef AFIO_DISABLE_PATHS_IN_FAILURE_INFO -namespace detail + +//! Helper for constructing an error code from an errc +inline error_code generic_error(errc c) { - template <class T> - inline error_domain_value_type<T>::error_domain_value_type(T _sc) // NOLINT - : ec(_sc) + SYSTEM_ERROR2_NAMESPACE::status_code<error_domain<SYSTEM_ERROR2_NAMESPACE::generic_code::domain_type>> sc(c); + if(sc.failure()) { - // Here is a VERY useful place to breakpoint! - if(ec.failure()) - { - detail::fill_failure_info(*this); - } + detail::fill_failure_info(sc.value(), sc); + } + return sc; +} +#ifndef _WIN32 +//! Helper for constructing an error code from a POSIX errno +inline error_code posix_error(int c) +{ + SYSTEM_ERROR2_NAMESPACE::status_code<error_domain<SYSTEM_ERROR2_NAMESPACE::posix_code::domain_type>> sc(c); + if(sc.failure()) + { + detail::fill_failure_info(sc.value(), sc); } + return sc; } +#else +//! Helper for constructing an error code from a DWORD +inline error_code win32_error(SYSTEM_ERROR2_NAMESPACE::win32::DWORD c) +{ + SYSTEM_ERROR2_NAMESPACE::status_code<error_domain<SYSTEM_ERROR2_NAMESPACE::win32_code::domain_type>> sc(c); + if(sc.failure()) + { + detail::fill_failure_info(sc.value(), sc); + } + return sc; +} +//! Helper for constructing an error code from a NTSTATUS +inline error_code ntkernel_error(SYSTEM_ERROR2_NAMESPACE::win32::NTSTATUS c) +{ + SYSTEM_ERROR2_NAMESPACE::status_code<error_domain<SYSTEM_ERROR2_NAMESPACE::nt_code::domain_type>> sc(c); + if(sc.failure()) + { + detail::fill_failure_info(sc.value(), sc); + } + return sc; +} +#endif + #endif #else // AFIO_EXPERIMENTAL_STATUS_CODE @@ -493,7 +525,7 @@ inline error_info::error_info(std::error_code _ec) #ifndef AFIO_DISABLE_PATHS_IN_FAILURE_INFO if(ec) { - detail::fill_failure_info(*this); + detail::fill_failure_info(*this, this->ec); } #endif } diff --git a/include/afio/v2.0/stat.hpp b/include/afio/v2.0/stat.hpp index 276ff581..c8cd5d4d 100644 --- a/include/afio/v2.0/stat.hpp +++ b/include/afio/v2.0/stat.hpp @@ -143,7 +143,7 @@ struct stat_t // NOLINT auto v(fill(h, wanted)); if(v.has_error()) { - v.error().throw_as_exception(); + v.error().throw_exception(); } } #endif diff --git a/include/afio/v2.0/statfs.hpp b/include/afio/v2.0/statfs.hpp index 34f92070..7f0ae23b 100644 --- a/include/afio/v2.0/statfs.hpp +++ b/include/afio/v2.0/statfs.hpp @@ -88,7 +88,7 @@ struct AFIO_DECL statfs_t auto v(fill(h, wanted)); if(v.has_error()) { - v.error().throw_as_exception(); + v.error().throw_exception(); } } #endif diff --git a/include/afio/v2.0/storage_profile.hpp b/include/afio/v2.0/storage_profile.hpp index 97205d7e..36d50749 100644 --- a/include/afio/v2.0/storage_profile.hpp +++ b/include/afio/v2.0/storage_profile.hpp @@ -27,6 +27,13 @@ Distributed under the Boost Software License, Version 1.0. #include "io_service.hpp" +#if AFIO_EXPERIMENTAL_STATUS_CODE +#include "outcome/include/outcome/experimental/status_outcome.hpp" +AFIO_V2_NAMESPACE_EXPORT_BEGIN +template <class T> using outcome = OUTCOME_V2_NAMESPACE::experimental::erased_outcome<T, error_code>; +AFIO_V2_NAMESPACE_END +#endif + #include <regex> #include <utility> //! \file storage_profile.hpp Provides storage_profile diff --git a/test/tests/current_path.cpp b/test/tests/current_path.cpp index 3f2ae559..23346a8c 100644 --- a/test/tests/current_path.cpp +++ b/test/tests/current_path.cpp @@ -50,7 +50,7 @@ template <class FileHandleType, class DirectoryHandleType> static inline void Te BOOST_CHECK(h1path); if(!h1path) { - std::cerr << "Getting the current path of a file FAILED due to " << h1path.error().message() << std::endl; + std::cerr << "Getting the current path of a file FAILED due to " << h1path.error().message().c_str() << std::endl; } else if(h1path.value().empty()) { @@ -66,7 +66,7 @@ template <class FileHandleType, class DirectoryHandleType> static inline void Te BOOST_CHECK(h2path); if(!h2path) { - std::cerr << "Getting the current path of a directory FAILED due to " << h2path.error().message() << std::endl; + std::cerr << "Getting the current path of a directory FAILED due to " << h2path.error().message().c_str() << std::endl; } else if(h2path.value().empty()) { @@ -87,7 +87,7 @@ template <class FileHandleType, class DirectoryHandleType> static inline void Te BOOST_CHECK(h1path); if(!h1path) { - std::cerr << "Getting the current path of a file FAILED due to " << h1path.error().message() << std::endl; + std::cerr << "Getting the current path of a file FAILED due to " << h1path.error().message().c_str() << std::endl; } else if(h1path.value().empty()) { @@ -108,7 +108,7 @@ template <class FileHandleType, class DirectoryHandleType> static inline void Te BOOST_CHECK(h2path); if(!h2path) { - std::cerr << "Getting the current path of a directory FAILED due to " << h2path.error().message() << std::endl; + std::cerr << "Getting the current path of a directory FAILED due to " << h2path.error().message().c_str() << std::endl; } else if(h2path.value().empty()) { @@ -133,7 +133,7 @@ template <class FileHandleType, class DirectoryHandleType> static inline void Te BOOST_CHECK(h1path); if(!h1path) { - std::cerr << "Getting the current path of a file FAILED due to " << h1path.error().message() << std::endl; + std::cerr << "Getting the current path of a file FAILED due to " << h1path.error().message().c_str() << std::endl; } else if(h1path.value().empty()) { diff --git a/test/tests/directory_handle_create_close/runner.cpp b/test/tests/directory_handle_create_close/runner.cpp index c052089a..90b1fa1d 100644 --- a/test/tests/directory_handle_create_close/runner.cpp +++ b/test/tests/directory_handle_create_close/runner.cpp @@ -37,7 +37,7 @@ template <class U> inline void directory_handle_create_close_creation(U &&f) // clang-format off static typename directory_handle::buffer_type _entries[5]; static typename directory_handle::buffers_type entries(_entries); - static result<typename directory_handle::enumerate_info> info(AFIO_V2_NAMESPACE::error_info{}); + static result<typename directory_handle::enumerate_info> info(typename result<typename directory_handle::enumerate_info>::error_type{}); static const auto permuter(mt_permute_parameters< result<void>, parameters< @@ -87,7 +87,7 @@ template <class U> inline void directory_handle_create_close_creation(U &&f) i = typename directory_handle::buffer_type(); } entries = typename directory_handle::buffers_type(_entries); - info = AFIO_V2_NAMESPACE::error_info(); + info = typename result<typename directory_handle::enumerate_info>::error_type(); return std::make_tuple(std::ref(permuter), std::ref(testreturn), idx, std::ref(enumeration_should_be)); }, [&](auto /*tuplestate*/) { |