Replace errno_error with std::system_error

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2023-10-01 22:56:45 +02:00
parent b8fae2d0dd
commit 49b741c94f
6 changed files with 48 additions and 110 deletions

View File

@ -1,4 +1,4 @@
/* /*
SPDX-License-Identifier: MIT SPDX-License-Identifier: MIT
Copyright © 2023 Amebis Copyright © 2023 Amebis
*/ */
@ -7,7 +7,6 @@
#include <stdex/base64.hpp> #include <stdex/base64.hpp>
#include <stdex/compat.hpp> #include <stdex/compat.hpp>
#include <stdex/errno.hpp>
#include <stdex/exception.hpp> #include <stdex/exception.hpp>
#include <stdex/hash.hpp> #include <stdex/hash.hpp>
#include <stdex/hex.hpp> #include <stdex/hex.hpp>

View File

@ -1,77 +0,0 @@
/*
SPDX-License-Identifier: MIT
Copyright © 2023 Amebis
*/
#pragma once
#include "compat.hpp"
#include <stdexcept>
#include <cstring>
namespace stdex
{
///
/// Standard C runtime library error
///
class errno_error : public std::runtime_error
{
public:
///
/// Constructs an exception
///
/// \param[in] num Numeric error code
/// \param[in] msg Error message
///
errno_error(_In_ errno_t num, _In_ const std::string& msg) :
m_num(num),
runtime_error(msg)
{
}
///
/// Constructs an exception
///
/// \param[in] num Numeric error code
/// \param[in] msg Error message
///
errno_error(_In_ errno_t num, _In_opt_z_ const char *msg = nullptr) :
m_num(num),
runtime_error(msg)
{
}
///
/// Constructs an exception using `GetLastError()`
///
/// \param[in] msg Error message
///
errno_error(_In_ const std::string& msg) :
m_num(errno),
runtime_error(msg)
{
}
///
/// Constructs an exception using `GetLastError()`
///
/// \param[in] msg Error message
///
errno_error(_In_opt_z_ const char *msg = nullptr) :
m_num(errno),
runtime_error(msg)
{
}
///
/// Returns the error number
///
errno_t number() const
{
return m_num;
}
protected:
errno_t m_num; ///< Numeric error code
};
}

View File

@ -21,7 +21,6 @@ namespace stdex
/// ///
/// \param[in] msg Error message /// \param[in] msg Error message
/// ///
user_cancelled(_In_opt_z_ const char* msg = "operation cancelled") : runtime_error(msg) user_cancelled(_In_opt_z_ const char* msg = "operation cancelled") : runtime_error(msg) {}
{}
}; };
} }

View File

@ -210,7 +210,7 @@ namespace stdex
uint8_t byte; uint8_t byte;
if (read_array(&byte, sizeof(byte), 1) == 1) if (read_array(&byte, sizeof(byte), 1) == 1)
return byte; return byte;
throw std::runtime_error("failed to read"); throw std::system_error(sys_error(), std::system_category(), "failed to read");
} }
/// ///
@ -846,10 +846,10 @@ namespace stdex
if (!sa) if (!sa)
throw std::runtime_error("SafeArrayCreateVector failed"); throw std::runtime_error("SafeArrayCreateVector failed");
safearray_accessor<void> a(sa.get()); safearray_accessor<void> a(sa.get());
if (seek(0) != 0) if (seek(0) != 0) _Unlikely_
throw std::runtime_error("failed to seek"); throw std::system_error(sys_error(), std::system_category(), "failed to seek");
if (read_array(a.data(), 1, length) != length) if (read_array(a.data(), 1, length) != length)
throw std::runtime_error("failed to read"); throw std::system_error(sys_error(), std::system_category(), "failed to read");
return sa.release(); return sa.release();
} }
#endif #endif
@ -861,29 +861,29 @@ namespace stdex
/// ///
charset_id read_charset(_In_ charset_id default_charset = charset_id::system) charset_id read_charset(_In_ charset_id default_charset = charset_id::system)
{ {
if (seek(0) != 0) if (seek(0) != 0) _Unlikely_
throw std::runtime_error("failed to seek"); throw std::system_error(sys_error(), std::system_category(), "failed to seek");
char32_t id_utf32; char32_t id_utf32;
read_array(&id_utf32, sizeof(char32_t), 1); read_array(&id_utf32, sizeof(char32_t), 1);
if (ok() && id_utf32 == utf32_bom) if (ok() && id_utf32 == utf32_bom)
return charset_id::utf32; return charset_id::utf32;
if (seek(0) != 0) if (seek(0) != 0) _Unlikely_
throw std::runtime_error("failed to seek"); throw std::system_error(sys_error(), std::system_category(), "failed to seek");
char16_t id_utf16; char16_t id_utf16;
read_array(&id_utf16, sizeof(char16_t), 1); read_array(&id_utf16, sizeof(char16_t), 1);
if (ok() && id_utf16 == utf16_bom) if (ok() && id_utf16 == utf16_bom)
return charset_id::utf16; return charset_id::utf16;
if (seek(0) != 0) if (seek(0) != 0) _Unlikely_
throw std::runtime_error("failed to seek"); throw std::system_error(sys_error(), std::system_category(), "failed to seek");
char id_utf8[3] = { 0 }; char id_utf8[3] = { 0 };
read_array(id_utf8, sizeof(id_utf8), 1); read_array(id_utf8, sizeof(id_utf8), 1);
if (ok() && strncmp(id_utf8, _countof(id_utf8), utf8_bom, _countof(utf8_bom)) == 0) if (ok() && strncmp(id_utf8, _countof(id_utf8), utf8_bom, _countof(utf8_bom)) == 0)
return charset_id::utf8; return charset_id::utf8;
if (seek(0) != 0) if (seek(0) != 0) _Unlikely_
throw std::runtime_error("failed to seek"); throw std::system_error(sys_error(), std::system_category(), "failed to seek");
return default_charset; return default_charset;
} }
}; };
@ -1716,7 +1716,7 @@ namespace stdex
if (m_source) { if (m_source) {
flush_cache(); flush_cache();
if (!ok()) _Unlikely_ if (!ok()) _Unlikely_
throw std::runtime_error("cache flush failed"); // Data loss occured throw std::system_error(sys_error(), std::system_category(), "failed to flush cache"); // Data loss occured
m_source->seek(m_offset); m_source->seek(m_offset);
m_source = nullptr; m_source = nullptr;
} }
@ -1739,7 +1739,7 @@ namespace stdex
if (m_source) { if (m_source) {
flush_cache(); flush_cache();
if (!ok()) _Unlikely_ if (!ok()) _Unlikely_
throw std::runtime_error("cache flush failed"); // Data loss occured throw std::system_error(sys_error(), std::system_category(), "failed to flush cache"); // Data loss occured
m_source->seek(m_offset); m_source->seek(m_offset);
} }
} }
@ -1863,7 +1863,7 @@ namespace stdex
{ {
invalidate_cache(); invalidate_cache();
if (!ok()) _Unlikely_ if (!ok()) _Unlikely_
throw std::runtime_error("cache flush failed"); // Data loss occured throw std::system_error(sys_error(), std::system_category(), "failed to flush cache"); // Data loss occured
m_source->close(); m_source->close();
m_state = m_source->state(); m_state = m_source->state();
} }
@ -2741,8 +2741,10 @@ namespace stdex
tp2ft(date, ft); tp2ft(date, ft);
if (SetFileTime(m_h, &ft, nullptr, nullptr)) if (SetFileTime(m_h, &ft, nullptr, nullptr))
return; return;
throw std::system_error(GetLastError(), std::system_category(), "SetFileTime failed");
#else
throw std::runtime_error("not supported");
#endif #endif
throw std::runtime_error("failed to set file ctime");
} }
virtual void set_atime(time_point date) virtual void set_atime(time_point date)
@ -2753,6 +2755,7 @@ namespace stdex
tp2ft(date, ft); tp2ft(date, ft);
if (SetFileTime(m_h, nullptr, &ft, nullptr)) if (SetFileTime(m_h, nullptr, &ft, nullptr))
return; return;
throw std::system_error(GetLastError(), std::system_category(), "SetFileTime failed");
#else #else
struct timespec ts[2] = { struct timespec ts[2] = {
{ date.time_since_epoch().count(), 0 }, { date.time_since_epoch().count(), 0 },
@ -2760,8 +2763,8 @@ namespace stdex
}; };
if (futimens(m_h, ts) >= 0) if (futimens(m_h, ts) >= 0)
return; return;
throw std::system_error(errno, std::system_category(), "futimens failed");
#endif #endif
throw std::runtime_error("failed to set file atime");
} }
virtual void set_mtime(time_point date) virtual void set_mtime(time_point date)
@ -2771,6 +2774,7 @@ namespace stdex
tp2ft(date, ft); tp2ft(date, ft);
if (SetFileTime(m_h, nullptr, nullptr, &ft)) if (SetFileTime(m_h, nullptr, nullptr, &ft))
return; return;
throw std::system_error(GetLastError(), std::system_category(), "SetFileTime failed");
#else #else
struct timespec ts[2] = { struct timespec ts[2] = {
{ 0, UTIME_OMIT }, { 0, UTIME_OMIT },
@ -2778,8 +2782,8 @@ namespace stdex
}; };
if (futimens(m_h, ts) >= 0) if (futimens(m_h, ts) >= 0)
return; return;
throw std::system_error(errno, std::system_category(), "futimens failed");
#endif #endif
throw std::runtime_error("failed to set file mtime");
} }
/// ///

View File

@ -55,6 +55,15 @@ namespace stdex
const sys_handle invalid_handle = (sys_handle)-1; const sys_handle invalid_handle = (sys_handle)-1;
#endif #endif
///
/// Last operation error
///
#if defined(_WIN32)
inline DWORD sys_error() { return GetLastError(); }
#else
inline int sys_error() { return errno; }
#endif
/// ///
/// Character type for system functions /// Character type for system functions
/// ///
@ -153,11 +162,13 @@ namespace stdex
{ {
#ifdef _WIN32 #ifdef _WIN32
if (CloseHandle(h) || GetLastError() == ERROR_INVALID_HANDLE) if (CloseHandle(h) || GetLastError() == ERROR_INVALID_HANDLE)
return;
throw std::system_error(GetLastError(), std::system_category(), "CloseHandle failed");
#else #else
if (::close(h) >= 0 || errno == EBADF) if (::close(h) >= 0 || errno == EBADF)
#endif
return; return;
throw std::runtime_error("failed to close handle"); throw std::system_error(errno, std::system_category(), "close failed");
#endif
} }
/// ///
@ -169,12 +180,14 @@ namespace stdex
#ifdef _WIN32 #ifdef _WIN32
HANDLE process = GetCurrentProcess(); HANDLE process = GetCurrentProcess();
if (DuplicateHandle(process, h, process, &h_new, 0, inherit, DUPLICATE_SAME_ACCESS)) if (DuplicateHandle(process, h, process, &h_new, 0, inherit, DUPLICATE_SAME_ACCESS))
return h_new;
throw std::system_error(GetLastError(), std::system_category(), "DuplicateHandle failed");
#else #else
_Unreferenced_(inherit); _Unreferenced_(inherit);
if ((h_new = dup(h)) >= 0) if ((h_new = dup(h)) >= 0)
#endif
return h_new; return h_new;
throw std::runtime_error("failed to duplicate handle"); throw std::system_error(errno, std::system_category(), "dup failed");
#endif
} }
protected: protected:
@ -190,7 +203,7 @@ namespace stdex
{ {
HRESULT hr = SafeArrayAccessData(sa, reinterpret_cast<void HUGEP**>(&m_data)); HRESULT hr = SafeArrayAccessData(sa, reinterpret_cast<void HUGEP**>(&m_data));
if (FAILED(hr)) if (FAILED(hr))
throw std::invalid_argument("SafeArrayAccessData failed"); throw std::system_error(hr, std::system_category(), "SafeArrayAccessData failed");
} }
~safearray_accessor() ~safearray_accessor()

View File

@ -69,7 +69,7 @@ namespace stdex
#else #else
m_handle = iconv_open(to_encoding(to), to_encoding(from)); m_handle = iconv_open(to_encoding(to), to_encoding(from));
if (m_handle == (iconv_t)-1) if (m_handle == (iconv_t)-1)
throw std::runtime_error("iconv_open failed"); throw std::system_error(errno, std::system_category(), "iconv_open failed");
#endif #endif
} }
@ -131,7 +131,7 @@ namespace stdex
dst.append(reinterpret_cast<const T_to*>(szBuffer.get()), count_src != SIZE_MAX ? wcsnlen(szBuffer.get(), cch) : static_cast<size_t>(cch) - 1); dst.append(reinterpret_cast<const T_to*>(szBuffer.get()), count_src != SIZE_MAX ? wcsnlen(szBuffer.get(), cch) : static_cast<size_t>(cch) - 1);
return; return;
} }
throw std::runtime_error("MultiByteToWideChar failed"); throw std::system_error(GetLastError(), std::system_category(), "MultiByteToWideChar failed");
} }
if _Constexpr_ (sizeof(T_from) == sizeof(wchar_t) && sizeof(T_to) == sizeof(char)) { if _Constexpr_ (sizeof(T_from) == sizeof(wchar_t) && sizeof(T_to) == sizeof(char)) {
@ -154,7 +154,7 @@ namespace stdex
dst.append(reinterpret_cast<const T_to*>(szBuffer.get()), count_src != SIZE_MAX ? strnlen(szBuffer.get(), cch) : static_cast<size_t>(cch) - 1); dst.append(reinterpret_cast<const T_to*>(szBuffer.get()), count_src != SIZE_MAX ? strnlen(szBuffer.get(), cch) : static_cast<size_t>(cch) - 1);
return; return;
} }
throw std::runtime_error("WideCharToMultiByte failed"); throw std::system_error(GetLastError(), std::system_category(), "WideCharToMultiByte failed");
} }
if _Constexpr_ (sizeof(T_from) == sizeof(char) && sizeof(T_to) == sizeof(char)) { if _Constexpr_ (sizeof(T_from) == sizeof(char) && sizeof(T_to) == sizeof(char)) {
@ -186,7 +186,7 @@ namespace stdex
dst.append(reinterpret_cast<const T_to*>(szBufferWCMB.get()), strnlen(szBufferWCMB.get(), cch)); dst.append(reinterpret_cast<const T_to*>(szBufferWCMB.get()), strnlen(szBufferWCMB.get(), cch));
return; return;
} }
throw std::runtime_error("WideCharToMultiByte failed"); throw std::system_error(GetLastError(), std::system_category(), "WideCharToMultiByte failed");
} }
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// Query the required output size. Allocate buffer. Then convert again. // Query the required output size. Allocate buffer. Then convert again.
@ -202,7 +202,7 @@ namespace stdex
dst.append(reinterpret_cast<const T_to*>(szBufferWCMB.get()), strnlen(szBufferWCMB.get(), cch)); dst.append(reinterpret_cast<const T_to*>(szBufferWCMB.get()), strnlen(szBufferWCMB.get(), cch));
return; return;
} }
throw std::runtime_error("MultiByteToWideChar failed"); throw std::system_error(GetLastError(), std::system_category(), "MultiByteToWideChar failed");
} }
#else #else
dst.reserve(dst.size() + count_src); dst.reserve(dst.size() + count_src);
@ -218,7 +218,7 @@ namespace stdex
break; break;
if (errno == E2BIG) if (errno == E2BIG)
continue; continue;
throw std::runtime_error("iconv failed"); throw std::system_error(errno, std::system_category(), "iconv failed");
} }
#endif #endif
} }