diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | includes/MMap.h | 2 | ||||
-rw-r--r-- | src/MMap.cc | 56 |
3 files changed, 53 insertions, 6 deletions
@@ -48,6 +48,7 @@ BRegex.cc \ Handle.cc \ Input.cc \ Output.cc \ +MMap.cc \ Socket.cc \ Selectable.cc \ Buffer.cc \ diff --git a/includes/MMap.h b/includes/MMap.h index ad55e4c..b43f9e1 100644 --- a/includes/MMap.h +++ b/includes/MMap.h @@ -12,7 +12,7 @@ class MMap : public Buffer { virtual ~MMap() override; void open() throw (GeneralException); virtual const char * getName() override { return m_name.to_charp(); } - virtual void close() override; + virtual void close() throw (GeneralException) override; private: MMapPlatform * m_platform = NULL; String m_name; diff --git a/src/MMap.cc b/src/MMap.cc index 18187b4..a984f00 100644 --- a/src/MMap.cc +++ b/src/MMap.cc @@ -2,6 +2,12 @@ #ifdef _WIN32 #include <windows.h> +#else +#include <sys/types.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> #endif namespace Balau { @@ -28,7 +34,7 @@ class MMapPlatform { if (m_handle == INVALID_HANDLE_VALUE) return std::tie(result, m_ptr, s); - ScopedLambda hc([&]() { if (!result) CloseHandle(m_handle); }); + ScopedLambda hc([&]() { if (!result) CloseHandle(m_handle); m_handle = INVALID_HANDLE_VALUE; }); LARGE_INTEGER fsize; if (!GetFileSizeEx(m_handle, (PLARGE_INTEGER) &fsize)) @@ -42,7 +48,7 @@ class MMapPlatform { return std::tie(result, m_ptr, s); // than getting the usual INVALID_HANDLE_VALUE (which is -1), // in order to make a sane and uniform API... { - ScopedLambda mc([&]() { if (!result) CloseHandle(m_mapObject); }); + ScopedLambda mc([&]() { if (!result) CloseHandle(m_mapObject); m_mapObject = (HANDLE) NULL; }); // and of course, CreateFileMapping takes the 64 bits size in high / low format, // whereas MapViewOfFile takes the 64 bits size in a single 64 bits size_t. Sure. Makes sense. @@ -69,17 +75,56 @@ class MMapPlatform { const uint8_t * m_ptr = NULL; }; +#else + +class MMapPlatform { + public: + std::tuple<bool, const uint8_t *, size_t> open(const String & fname) { + bool result = false; + m_size = 0; + m_fd = ::open(fname.to_charp(), O_RDONLY); + + if (m_fd < 0) + return std::tie(result, m_ptr, m_size); + + ScopedLambda hc([&]() { if (!result) ::close(m_fd); m_fd = -1; }); + + m_size = lseek(m_fd, 0, SEEK_END); + lseek(m_fd, 0, SEEK_SET); + + if (m_size < 0) + return std::tie(result, m_ptr, m_size); + + m_ptr = (uint8_t *) mmap(NULL, m_size, PROT_READ, MAP_PRIVATE, m_fd, 0); + + result = !!m_ptr; + + return std::tie(result, m_ptr, m_size); + } + void close() { + if (m_ptr) + munmap(m_ptr, m_size); + if (m_fd >= 0) + ::close(m_fd); + m_ptr = NULL; + m_fd = -1; + } + int m_fd = -1; + uint8_t * m_ptr = NULL; + ssize_t m_size; +}; + #endif }; Balau::MMap::MMap(const char * fname) { m_fname = fname; - m_name.set("mmap of %s", m_fname); + m_name.set("mmap of %s", m_fname.to_charp()); m_platform = new MMapPlatform(); } -void Balau::MMap::open() { +void Balau::MMap::open() throw (GeneralException) { bool result; const uint8_t * ptr; size_t s; @@ -90,11 +135,12 @@ void Balau::MMap::open() { borrow(ptr, s); } -void Balau::MMap::close() { +void Balau::MMap::close() throw (GeneralException) { m_platform->close(); Buffer::close(); } Balau::MMap::~MMap() { + m_platform->close(); delete m_platform; } |