summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/Handle.h4
-rw-r--r--lib/Handle.cc54
2 files changed, 50 insertions, 8 deletions
diff --git a/include/Handle.h b/include/Handle.h
index 64e082b..79799da 100644
--- a/include/Handle.h
+++ b/include/Handle.h
@@ -42,6 +42,7 @@ class Handle : public Base {
virtual void Flush();
void * mmap(off_t = 0, size_t = -1) throw (GeneralException);
+ void munmap() throw (GeneralException);
protected:
Handle(int h);
int GetHandle() const;
@@ -56,6 +57,9 @@ class Handle : public Base {
z_stream zstrm;
int z, c;
void * hMapObject;
+ bool mapped;
+ size_t maplength;
+ void * mappedarea;
};
Handle & operator<<(Handle &, const String &);
diff --git a/lib/Handle.cc b/lib/Handle.cc
index 4b2b4f1..8ec6219 100644
--- a/lib/Handle.cc
+++ b/lib/Handle.cc
@@ -37,7 +37,7 @@ enum {
INFLATE
};
-Handle::Handle(const Handle & nh) : itell(0), hFile(0), h(nh.h >= 0 ? dup(nh.h) : nh.h), closed(nh.closed), nonblock(nh.closed), zfile(0), z(0)
+Handle::Handle(const Handle & nh) : itell(0), hFile(0), h(nh.h >= 0 ? dup(nh.h) : nh.h), closed(nh.closed), nonblock(nh.closed), zfile(0), z(0), hMapObject(0), mapped(0)
{
#ifdef DEBUG
printm(M_INFO, String(_("Duplication of handle ")) + nh.h + _(" to ") + h + "\n");
@@ -54,7 +54,7 @@ Handle::~Handle() {
close();
}
-Handle::Handle(int nh) : h(nh), closed(false), nonblock(false), zfile(0), z(0)
+Handle::Handle(int nh) : h(nh), closed(false), nonblock(false), zfile(0), z(0), hMapObject(0), mapped(0)
{
#ifdef DEBUG
printm(M_INFO, String(_("Initialising handle ")) + h + "\n");
@@ -255,6 +255,10 @@ void Handle::close() throw (GeneralException) {
hFile = 0;
}
#endif
+
+ if (mapped) {
+ munmap();
+ }
h = -1;
closed = 1;
@@ -522,16 +526,25 @@ void Handle::Flush() {
}
void * Handle::mmap(off_t offset, size_t length) throw (GeneralException) {
+ void * r;
+
if (h == -1) {
throw GeneralException("Can't mmap() a virtual handle");
}
+ if (mapped) {
+ throw GeneralException("Handle already mmap()ped");
+ }
+ mapped = true;
+ maplength = length;
if (length == -1) {
length = GetSize();
}
-#ifndef _WIN32
- return ::mmap(0, length, (CanRead() ? PROT_READ : 0) | (CanWrite() ? PROT_WRITE : 0), MAP_SHARED, h, offset);
+#ifndef _WIN32
+ r = ::mmap(0, length, (CanRead() ? PROT_READ : 0) | (CanWrite() ? PROT_WRITE : 0), MAP_SHARED, h, offset);
+ if (!r) {
+ throw GeneralException(String("Was not able to mmap(): ") + strerror(errno));
+ }
#else
- void * lpvMem = 0;
hMapObject = CreateFileMapping(
hFile,
0,
@@ -540,16 +553,41 @@ void * Handle::mmap(off_t offset, size_t length) throw (GeneralException) {
length,
GetName().to_charp());
if (hMapObject != NULL) {
- lpvMem = MapViewOfFile(
+ r = MapViewOfFile(
hMapObject,
CanWrite() ? FILE_MAP_WRITE : FILE_MAP_READ,
0,
offset,
length);
- if (lpvMem == NULL) {
+ if (!r) {
CloseHandle(hMapObject);
+ throw GeneralException("Was not able to MapViewOfFile()");
}
+ } else {
+ throw GeneralException("Was not able to CreateFileMapping()");
}
- return lpvMem;
#endif
+
+ mappedarea = r;
+
+ return r;
+}
+
+void Handle::munmap() throw (GeneralException) {
+ if (!mapped) {
+ throw GeneralException("Can't munmap, was not mapped");
+ }
+#ifndef _WIN32
+ if (::munmap(mappedarea, maplength) {
+ throw GeneralException(String("Was not able to munmap(): ") + strerror(errno));
+ }
+#else
+ if (!UnmapViewOfFile(mappedarea)) {
+ throw GeneralException("Was not able to UnmapViewOfFile()");
+ }
+ CloseHandle(hMapObject);
+#endif
+ mapped = false;
+ mappedarea = 0;
+ maplength = 0;
}