summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--includes/MMap.h2
-rw-r--r--src/MMap.cc56
3 files changed, 53 insertions, 6 deletions
diff --git a/Makefile b/Makefile
index a3b36ec..c920641 100644
--- a/Makefile
+++ b/Makefile
@@ -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;
}