io_posix: fake the mapping of zero length files

This commit is contained in:
Danny Robson 2018-07-05 13:44:34 +10:00
parent a4844fa7ed
commit 8d921aacc2
2 changed files with 20 additions and 9 deletions

View File

@ -41,6 +41,11 @@ mapped_file::mapped_file (const ::util::posix::fd &src, int mflags)
::util::posix::error::try_value (fstat (src, &meta));
m_size = util::cast::sign<size_t> (meta.st_size);
if (!m_size) {
m_data = nullptr;
return;
}
m_data = static_cast<uint8_t*> (mmap (nullptr, m_size, mflags, MAP_SHARED, src, 0));
if (m_data == MAP_FAILED)
::util::posix::error::throw_code ();
@ -50,7 +55,9 @@ mapped_file::mapped_file (const ::util::posix::fd &src, int mflags)
//----------------------------------------------------------------------------
mapped_file::~mapped_file ()
{
CHECK (m_data != NULL);
if (!m_data)
return;
munmap (m_data, m_size);
}
@ -75,9 +82,6 @@ mapped_file::empty (void) const
uint8_t*
mapped_file::data (void) &
{
CHECK (m_size > 0);
CHECK (m_data != NULL);
return m_data;
}
@ -86,9 +90,6 @@ mapped_file::data (void) &
const uint8_t*
mapped_file::data (void) const &
{
CHECK (m_size > 0);
CHECK (m_data != NULL);
return m_data;
}

View File

@ -29,6 +29,11 @@
namespace util {
namespace detail::posix {
// represents a memory mapped file.
//
// the data pointer may be null in the case of a zero length file. it
// is expected that the user will take measures to avoid dereferencing
// such a pointer.
class mapped_file {
public:
using value_type = uint8_t;
@ -48,14 +53,19 @@ namespace util {
mapped_file (const mapped_file&) = delete;
mapped_file& operator= (const mapped_file&) = delete;
mapped_file (const mapped_file&&) noexcept;
mapped_file& operator= (mapped_file&&) noexcept;
~mapped_file ();
bool empty (void) const;
/// returns the total allocated mapped region in bytes.
///
/// result is typed size_t (rather than a signed type) because we
/// often use this in conjunction with sizeof and packed structure.
/// result is typed size_t (rather than the native signed type)
/// because we often use this in conjunction with sizeof and
/// packed structure.
///
/// it is greatly simpler to cast to signed where it's actually
/// required rather than the other way around.
size_type size (void) const;