except: move posix/win32 exceptions to own units

This commit is contained in:
Danny Robson 2017-12-18 15:46:52 +11:00
parent 2ead13a063
commit 77c88438d4
20 changed files with 73 additions and 376 deletions

View File

@ -80,6 +80,8 @@ list (
posix/dir.cpp
posix/dir.hpp
posix/dir.ipp
posix/except.cpp
posix/except.hpp
posix/fd.cpp
posix/fd.hpp
)
@ -120,6 +122,8 @@ if (WINDOWS)
library_win32.hpp
library_win32.cpp
time_win32.cpp
win32/except.cpp
win32/except.hpp
win32/handle.cpp
win32/handle.hpp
win32/registry.hpp
@ -201,8 +205,6 @@ list (
debug.ipp
endian.cpp
endian.hpp
except.cpp
except.hpp
exe.hpp
extent.cpp
extent.hpp

View File

@ -19,6 +19,7 @@
#include "debug.hpp"
#include "except.hpp"
#include "types.hpp"
#include "win32/error.hpp"
#include <windows.h>
#include <dbghelp.h>
@ -66,7 +67,7 @@ backtrace::backtrace ()
SymGetModuleBase64,
nullptr))
{
util::win32_error::throw_code ();
util::win32::error::throw_code ();
}
// we've read the bottom of the stack

View File

@ -17,6 +17,7 @@
#include "backtrace.hpp"
#include "win32/error.hpp"
#include "win32/handle.hpp"
#include "debug.hpp"
#include "except.hpp"
@ -33,7 +34,7 @@ debug::backtrace::backtrace (void)
auto process = GetCurrentProcess();
if (!SymInitialize (process, NULL, TRUE))
util::win32_error::throw_code ();
util::win32::error::throw_code ();
while (true) {
auto res = CaptureStackBackTrace (1, m_frames.size (), m_frames.data (), NULL);

View File

@ -19,6 +19,7 @@
#include "except.hpp"
#include "log.hpp"
#include "except.hpp"
#include "win32/error.hpp"
#include <windows.h>
#include <iostream>
@ -49,7 +50,7 @@ prepare_debugger (void)
{
if (nullptr == LoadLibrary("exchndl.dll")) {
auto code = GetLastError ();
LOG_WARNING("Emergency debugger not loaded: %s", util::win32_error::code_string (code));
LOG_WARNING("Emergency debugger not loaded: %s", util::win32::error::code_string (code));
}
}

View File

@ -1,202 +0,0 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright 2010 Danny Robson <danny@nerdcruft.net>
*/
#include "except.hpp"
#include "debug.hpp"
#include "platform.hpp"
#include <cstring>
#include <cerrno>
using util::errno_error;
///////////////////////////////////////////////////////////////////////////////
/// Construct an errno_error from a given error value. The error value MUST signal an error at
/// construction time.
errno_error::errno_error (int _code):
runtime_error (strerror (_code)),
m_code (_code)
{
CHECK_NEQ (_code, 0);
}
///----------------------------------------------------------------------------
/// Construct an errno_error from the current value of errno. errno MUST signal an error at
/// construction time.
errno_error::errno_error ():
errno_error (last_code ())
{
CHECK_NEQ (m_code, 0);
}
///////////////////////////////////////////////////////////////////////////////
int
errno_error::last_code (void)
{
return errno;
}
//-----------------------------------------------------------------------------
int
errno_error::code (void) const
{
return m_code;
}
///////////////////////////////////////////////////////////////////////////////
/// Throw an errno_error exception if errno currently signals an error.
void
errno_error::try_code (void)
{
try_code (last_code ());
}
///----------------------------------------------------------------------------
/// Throw an errno_error exception if 'code' represents an error.
void
errno_error::try_code (int code)
{
if (__builtin_expect (code != 0, false))
throw errno_error(code);
}
///----------------------------------------------------------------------------
void
errno_error::throw_code (void)
{
throw_code (last_code ());
}
///----------------------------------------------------------------------------
void
errno_error::throw_code (int code)
{
CHECK_NEQ (code, 0);
throw errno_error (code);
}
///////////////////////////////////////////////////////////////////////////////
#if defined(PLATFORM_WIN32)
using util::win32_error;
//-----------------------------------------------------------------------------
win32_error::win32_error (DWORD _code):
runtime_error (code_string (_code)),
m_code (_code)
{
CHECK_NEQ (m_code, (DWORD)ERROR_SUCCESS);
}
//-----------------------------------------------------------------------------
win32_error::win32_error (void):
win32_error (last_code ())
{ ; }
///////////////////////////////////////////////////////////////////////////////
DWORD
win32_error::code (void) const
{
return m_code;
}
//-----------------------------------------------------------------------------
DWORD
win32_error::last_code (void)
{
return GetLastError ();
}
///////////////////////////////////////////////////////////////////////////////
void
win32_error::try_code (void)
{
try_code (last_code ());
}
//-----------------------------------------------------------------------------
void
win32_error::try_code (DWORD id)
{
if (__builtin_expect (id != ERROR_SUCCESS, false))
throw_code (id);
}
//-----------------------------------------------------------------------------
void
win32_error::throw_code (void)
{
throw_code (last_code ());
}
//-----------------------------------------------------------------------------
void
win32_error::throw_code (DWORD code)
{
CHECK_NEQ (code, (DWORD)ERROR_SUCCESS);
throw win32_error (code);
}
//-----------------------------------------------------------------------------
std::string
win32_error::code_string (void)
{
return code_string (last_code ());
}
//-----------------------------------------------------------------------------
std::string
win32_error::code_string (DWORD code)
{
char message[256];
auto res = FormatMessage (
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
code,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
message,
std::size (message),
NULL
);
if (res == 0) {
win32_error::throw_code ();
}
return std::string (message, message + res);
}
#endif

View File

@ -1,97 +0,0 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright 2010 Danny Robson <danny@nerdcruft.net>
*/
#ifndef __EXCEPT_HPP
#define __EXCEPT_HPP
#include "platform.hpp"
#include <stdexcept>
namespace util {
class input_error : public std::runtime_error {
public:
explicit input_error (const std::string &_what):
runtime_error (_what)
{ ; }
};
class output_error : public std::runtime_error {
public:
explicit output_error (const std::string &_what):
runtime_error (_what)
{ ; }
};
class unavailable_error : public std::runtime_error {
public:
explicit unavailable_error (const std::string &_what):
runtime_error (_what)
{ ; }
};
/// An exception class used for reporting errors signalled by errno.
class errno_error : public std::runtime_error {
public:
explicit errno_error (int code);
errno_error ();
int code (void) const;
static int last_code (void);
static void try_code (void);
static void try_code (int code);
static void throw_code [[gnu::noreturn]] (void);
static void throw_code [[gnu::noreturn]] (int code);
private:
int m_code;
};
}
#if defined(PLATFORM_WIN32)
#include <windows.h>
namespace util {
class win32_error : public std::runtime_error {
public:
explicit win32_error (DWORD _code);
win32_error ();
DWORD code (void) const;
static DWORD last_code (void);
static void try_code (void);
static void try_code (DWORD);
static void throw_code [[gnu::noreturn]] (void);
static void throw_code [[gnu::noreturn]] (DWORD);
static std::string code_string (void);
static std::string code_string (DWORD);
private:
DWORD m_code;
};
}
#endif
#endif

View File

@ -16,8 +16,8 @@
#include "exe.hpp"
#include "except.hpp"
#include "cast.hpp"
#include "posix/except.hpp"
#include <vector>
#include <experimental/filesystem>
@ -39,7 +39,7 @@ util::image_path (void)
retry:
const auto written = readlink (PROC_SELF, resolved.data (), resolved.size ());
if (written < 0)
errno_error::throw_code ();
posix::error::throw_code ();
if (sign_cast<size_t> (written) == resolved.size ()) {
resolved.resize (resolved.size () * 2);

View File

@ -17,6 +17,7 @@
#include "exe.hpp"
#include "except.hpp"
#incldue "win32/except.hpp"
#include <experimental/filesystem>
#include <vector>
@ -32,7 +33,7 @@ util::image_path (void)
retry:
const auto written = GetModuleFileName (nullptr, resolved.data (), resolved.size ());
if (written == 0)
win32_error::throw_code ();
win32::error::throw_code ();
if (written == resolved.size ()) {
resolved.resize (resolved.size () * 2);

31
io.cpp
View File

@ -17,8 +17,8 @@
#include "io.hpp"
#include "debug.hpp"
#include "except.hpp"
#include "cast.hpp"
#include "posix/except.hpp"
#include <cstdio>
#include <fcntl.h>
@ -44,12 +44,9 @@ util::slurp (const std::experimental::filesystem::path &path)
posix::fd out (path, O_RDONLY | O_BINARY);
// Calculate the total file size
off_t size = lseek (out, 0, SEEK_END);
if (size == (off_t)-1)
throw errno_error();
off_t size = posix::error::try_value (lseek (out, 0, SEEK_END));
if (lseek (out, 0, SEEK_SET) == (off_t)-1)
throw errno_error ();
posix::error::try_value (lseek (out, 0, SEEK_SET));
// Allocate a buffer, and keep reading until it's full.
std::vector<T> buffer (size);
@ -59,9 +56,10 @@ util::slurp (const std::experimental::filesystem::path &path)
T *cursor = buffer.data ();
while (remaining) {
ssize_t consumed = ::read (out, cursor, remaining);
if (consumed == -1)
throw errno_error();
ssize_t consumed = posix::error::try_value(
::read (out, cursor, remaining)
);
CHECK_GT ( consumed, 0);
CHECK_LE ((size_t)consumed, remaining);
@ -89,13 +87,10 @@ util::slurp (FILE *stream)
);
// find how much data is in this file
const int desc = fileno (stream);
if (desc < 0)
errno_error::throw_code ();
const int desc = util::posix::error::try_value (fileno (stream));
struct stat meta;
if (fstat (desc, &meta) < 0)
errno_error::throw_code ();
posix::error::try_value (fstat (desc, &meta));
std::vector<T> buf;
@ -144,9 +139,7 @@ util::write (const posix::fd &out,
size_t remaining = bytes;
while (remaining) {
ssize_t consumed = ::write (out, cursor, remaining);
if (consumed < 0)
errno_error::throw_code ();
ssize_t consumed = posix::error::try_value (::write (out, cursor, remaining));
remaining -= sign_cast<size_t> (consumed);
cursor += sign_cast<size_t> (consumed);
@ -198,7 +191,7 @@ scoped_cwd::scoped_cwd ()
m_original.resize (16);
while (getcwd (&m_original[0], m_original.size ()) == nullptr && errno == ERANGE)
m_original.resize (m_original.size () * 2);
errno_error::try_code ();
posix::error::try_code ();
}
@ -206,7 +199,7 @@ scoped_cwd::scoped_cwd ()
scoped_cwd::~scoped_cwd ()
{
if (!chdir (m_original.c_str ()))
errno_error::throw_code ();
posix::error::throw_code ();
}

View File

@ -18,8 +18,8 @@
#include "cast.hpp"
#include "debug.hpp"
#include "except.hpp"
#include "posix/fd.hpp"
#include "posix/except.hpp"
#include <sys/stat.h>
@ -38,13 +38,12 @@ mapped_file::mapped_file (const std::experimental::filesystem::path &path,
mapped_file::mapped_file (const ::util::posix::fd &src, int mflags)
{
struct stat meta;
if (fstat (src, &meta) < 0)
throw errno_error ();
::util::posix::error::try_value (fstat (src, &meta));
m_size = sign_cast<size_t> (meta.st_size);
m_data = (uint8_t *)mmap (NULL, m_size, mflags, MAP_SHARED, src, 0);
if (m_data == MAP_FAILED)
throw errno_error ();
::util::posix::error::throw_code ();
}

View File

@ -18,6 +18,7 @@
#include "debug.hpp"
#include "except.hpp"
#include "win32/error.hpp"
#include <windows.h>
@ -94,11 +95,11 @@ mapped_file::mapped_file (::util::win32::handle &&src,
// hell. Try not to collapse, but instead bail with a null mapping and
// pray the user doesn't do something stupid with the result.
if (!m_mapping) {
auto err = win32_error::last_code ();
auto err = win32::error::last_code ();
if (err == ERROR_FILE_INVALID && m_size == 0)
return;
win32_error::throw_code (err);
win32::error::throw_code (err);
}
auto view = MapViewOfFile (
@ -109,7 +110,7 @@ mapped_file::mapped_file (::util::win32::handle &&src,
);
if (!view)
win32_error::throw_code ();
win32::error::throw_code ();
m_data.reset (
static_cast<unsigned char*> (view)

View File

@ -16,7 +16,7 @@
#include "library_win32.hpp"
#include "except.hpp"
#include "win32/except.hpp"
using util::detail::win32::library;
@ -26,7 +26,7 @@ library::library (const std::experimental::filesystem::path &path):
m_handle (LoadLibraryA (path.c_str ()))
{
if (!m_handle)
win32_error::throw_code ();
win32::error::throw_code ();
}

View File

@ -16,12 +16,12 @@
#include "circular.hpp"
#include "../system.hpp"
#include "../../debug.hpp"
#include "../../except.hpp"
#include "../../maths.hpp"
#include "../../posix/except.hpp"
#include "../../raii.hpp"
#include "../../random.hpp"
#include "../system.hpp"
#include <unistd.h>
#include <sys/mman.h>
@ -84,14 +84,14 @@ circular::circular (size_t bytes)
// embiggen to the desired size
if (ftruncate (fd, bytes))
errno_error::throw_code ();
posix::error::throw_code ();
// pre-allocate a sufficiently large virtual memory block. it doesn't
// matter much what flags we use because we'll just be overwriting it
// shortly.
m_begin = reinterpret_cast<char*> (mmap (nullptr, bytes * 2, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
if (MAP_FAILED == m_begin)
errno_error::throw_code ();
posix::error::throw_code ();
// preemptively setup an unmapping object in case the remapping fails
util::scoped_function unmapper ([this, bytes] (void) { munmap (m_begin, bytes); });
@ -105,7 +105,7 @@ circular::circular (size_t bytes)
m_end = reinterpret_cast<char*> (mmap (m_begin + bytes, bytes, prot, flag, fd, 0));
if (m_begin == MAP_FAILED || m_end == MAP_FAILED)
errno_error::throw_code ();
posix::error::throw_code ();
// all went well, disarm the failsafe
unmapper.clear ();

View File

@ -16,11 +16,11 @@
#include "paged.hpp"
#include "../system.hpp"
#include "../../except.hpp"
#include "../../cast.hpp"
#include "../../maths.hpp"
#include "../../pointer.hpp"
#include "../../cast.hpp"
#include "../../posix/except.hpp"
#include "../system.hpp"
#include <sys/mman.h>
@ -37,7 +37,7 @@ paged::paged (size_t bytes, size_t _window):
);
if (m_begin == MAP_FAILED)
errno_error::throw_code ();
posix::error::throw_code ();
// remap the initial window with read/write permissions
m_cursor = m_begin + round_up (min (m_window, bytes), pagesize ());
@ -45,7 +45,7 @@ paged::paged (size_t bytes, size_t _window):
m_cursor - m_begin,
PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))
errno_error::throw_code ();
posix::error::throw_code ();
// record the nominal end address
m_end = m_begin + round_up (bytes, pagesize ());
@ -110,7 +110,7 @@ paged::commit (char *cursor)
PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0))
errno_error::throw_code ();
posix::error::throw_code ();
m_cursor = cursor;
}
@ -137,7 +137,7 @@ paged::release (char *desired)
PROT_NONE,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0))
errno_error::throw_code ();
posix::error::throw_code ();
m_cursor = desired;
}

View File

@ -16,8 +16,8 @@
#include "system.hpp"
#include "../except.hpp"
#include "../cast.hpp"
#include "../posix/except.hpp"
#include <unistd.h>
@ -28,11 +28,7 @@ util::memory::pagesize (void)
static size_t val;
if (!val) {
auto res = sysconf (_SC_PAGE_SIZE);
if (res == -1)
errno_error::throw_code ();
val = sign_cast<unsigned long> (res);
val = sign_cast<unsigned long> (posix::error::try_value (sysconf (_SC_PAGE_SIZE)));
}
return val;

View File

@ -16,7 +16,7 @@
#include "dir.hpp"
#include "../except.hpp"
#include "except.hpp"
using util::posix::dir;
@ -26,14 +26,14 @@ dir::dir (const std::experimental::filesystem::path &p):
m_handle (::opendir (p.c_str ()))
{
if (!m_handle)
errno_error::throw_code ();
error::throw_code ();
}
//-----------------------------------------------------------------------------
dir::~dir ()
{
errno_error::try_code (closedir (m_handle));
error::try_code (closedir (m_handle));
}

View File

@ -14,7 +14,7 @@
* Copyright 2015-2016 Danny Robson <danny@nerdcruft.net>
*/
#include "../except.hpp"
#include "except.hpp"
#include <cerrno>
@ -29,7 +29,7 @@ util::posix::dir::scan(std::function<void(const std::experimental::filesystem::p
for (dirent *cursor; errno = 0, cursor = readdir (m_handle); )
cb (cursor->d_name, args...);
errno_error::try_code ();
error::try_code ();
}
@ -43,5 +43,5 @@ util::posix::dir::scan (void (*cb) (const std::experimental::filesystem::path&,
for (dirent *cursor; errno = 0, cursor = readdir (m_handle); )
cb (cursor->d_name, args...);
errno_error::try_code ();
error::try_code ();
}

View File

@ -16,7 +16,7 @@
#include "fd.hpp"
#include "../except.hpp"
#include "except.hpp"
#include <sys/stat.h>
#include <fcntl.h>
@ -36,7 +36,7 @@ fd::fd (const std::experimental::filesystem::path &path, int flags, mode_t mode)
m_fd (::open (path.c_str (), flags, mode))
{
if (m_fd < 0)
errno_error::throw_code ();
error::throw_code ();
}
@ -68,7 +68,7 @@ fd::dup (int _fd)
{
auto res = ::dup (_fd);
if (res < 0)
errno_error::throw_code ();
error::throw_code ();
return fd (res);
}
@ -81,7 +81,7 @@ fd::~fd ()
return;
if (close (m_fd))
errno_error::throw_code ();
error::throw_code ();
}
@ -91,7 +91,7 @@ fd::stat (void) const
{
struct stat buf;
if (fstat (m_fd, &buf))
errno_error::throw_code ();
error::throw_code ();
return buf;
}
@ -102,7 +102,7 @@ fd::read (void *buffer, size_t count)
{
auto res = ::read (m_fd, buffer, count);
if (res == -1)
errno_error::throw_code ();
error::throw_code ();
return res;
}
@ -112,7 +112,7 @@ fd::write (const void *buffer, size_t count)
{
auto res = ::write (m_fd, buffer, count);
if (res == -1)
errno_error::throw_code ();
error::throw_code ();
return res;
}
@ -123,7 +123,7 @@ fd::lseek (off_t offset, int whence)
{
auto res = ::lseek (m_fd, offset, whence);
if (res == -1)
errno_error::throw_code ();
error::throw_code ();
return res;
}

View File

@ -16,7 +16,7 @@
#include "map.hpp"
#include "../except.hpp"
#include "posix/except.hpp"
using util::posix::map;
@ -27,7 +27,7 @@ map::map (size_t size, int prot, int flags):
m_size (size)
{
if (MAP_FAILED == m_addr)
::util::errno_error::throw_code ();
::util::posix::error::throw_code ();
}
@ -37,7 +37,7 @@ map::map (size_t size, int prot, int flags, const fd &src, off_t offset):
m_size (size)
{
if (MAP_FAILED == m_addr)
::util::errno_error::throw_code ();
::util::posix::error::throw_code ();
}
@ -57,7 +57,7 @@ map::~map ()
return;
if (munmap (m_addr, m_size))
::util::errno_error::throw_code ();
::util::posix::error::throw_code ();
}
@ -136,5 +136,5 @@ map::resize (size_t newsize, resize_t op)
auto res = mremap (m_addr, m_size, newsize, flags);
if (res == MAP_FAILED)
::util::errno_error::throw_code ();
::util::posix::error::throw_code ();
}

View File

@ -16,6 +16,7 @@
#include "registry.hpp"
#include "error.hpp"
#include "../debug.hpp"
#include "../except.hpp"
@ -50,7 +51,7 @@ template <> constexpr DWORD restrict_to_id<std::string> (void) { return RRF_RT_R
key::key (HKEY root, const char *child, REGSAM rights)
{
auto err = RegOpenKeyEx (root, child, 0, rights, &m_handle);
win32_error::try_code (err);
win32::error::try_code (err);
}
@ -58,7 +59,7 @@ key::key (HKEY root, const char *child, REGSAM rights)
key::~key ()
{
auto err = RegCloseKey (m_handle);
win32_error::try_code (err);
win32::error::try_code (err);
}
@ -72,7 +73,7 @@ key::data (const char *name) const
DWORD size = sizeof (value);
auto err = RegGetValue (m_handle, name, &value, restrict_to_id<T> (), nullptr, &value, &size);
win32_error::try_code (err);
win32::error::try_code (err);
return value;
}
@ -92,7 +93,7 @@ key::values (void) const
if (ERROR_NO_MORE_ITEMS == err)
return all;
if (ERROR_SUCCESS != err)
win32_error::throw_code (err);
win32::error::throw_code (err);
CHECK_GT (size, 0u);
name.resize (size - 1);