Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/llfio.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/afio/revision.hpp6
-rw-r--r--include/afio/v2.0/algorithm/shared_fs_mutex/memory_map.hpp6
-rw-r--r--include/afio/v2.0/config.hpp157
-rw-r--r--include/afio/v2.0/detail/impl/cached_parent_handle_adapter.ipp2
-rw-r--r--include/afio/v2.0/detail/impl/path_discovery.ipp4
-rw-r--r--include/afio/v2.0/detail/impl/posix/io_handle.ipp2
-rw-r--r--include/afio/v2.0/detail/impl/posix/path_discovery.ipp2
-rw-r--r--include/afio/v2.0/detail/impl/storage_profile.ipp44
-rw-r--r--include/afio/v2.0/detail/impl/windows/fs_handle.ipp2
-rw-r--r--include/afio/v2.0/detail/impl/windows/path_view.ipp5
-rw-r--r--include/afio/v2.0/handle.hpp62
-rw-r--r--include/afio/v2.0/stat.hpp2
-rw-r--r--include/afio/v2.0/statfs.hpp2
-rw-r--r--include/afio/v2.0/storage_profile.hpp7
-rw-r--r--test/tests/current_path.cpp10
-rw-r--r--test/tests/directory_handle_create_close/runner.cpp4
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*/) {