summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNicolas "Pixel" Noble <pixel@nobis-crew.org>2014-06-03 18:07:13 +0200
committerNicolas "Pixel" Noble <pixel@nobis-crew.org>2014-06-03 18:07:13 +0200
commit5044feb835653ba98ee48cf243fe5d3ab184fa3c (patch)
tree42e2f214506c88a7be98bd016174effc2479610f /src
parent0243f128ddc7ee44db1a8b95f76eb726122ee1d5 (diff)
Implementing MMap for Linux, and fixing a few details.
Diffstat (limited to 'src')
-rw-r--r--src/MMap.cc56
1 files changed, 51 insertions, 5 deletions
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;
}