aboutsummaryrefslogtreecommitdiffstats
path: root/modules/allocation/alloc_mmap/mmap_mem.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-09-28 15:34:09 +0000
committerlloyd <[email protected]>2008-09-28 15:34:09 +0000
commitea32d18231b9c6c5c84b3754c4249170d3b4e4c0 (patch)
treecc179337d0594ed105768011722b9dbae105e07a /modules/allocation/alloc_mmap/mmap_mem.cpp
parentb841401e095cfc1aa0708689d7920eb95ece71af (diff)
This is the first checkin to net.randombit.botan.modularized, which
has the intent of modularizing Botan's source code, and making it much easier to add or remove various things at compile time. In this first checkin: Add support for nested directories in modules/ and move all the modules into grouped directories like entropy/ or compression/ Currently this is not ideal, it will _only_ find code in modules/*/*/modinfo.txt, while it would be much better to allow for arbitrary nestings under modules (find modules -name modinfo.txt) for more complicated setups. This 'new' (OMG I've found directories!) structure allows for a more free naming convention (no need for leading es_, ml_, etc to group names, though some keep it for lack of a more meaningful name being obvious to me right at the moment).
Diffstat (limited to 'modules/allocation/alloc_mmap/mmap_mem.cpp')
-rw-r--r--modules/allocation/alloc_mmap/mmap_mem.cpp128
1 files changed, 128 insertions, 0 deletions
diff --git a/modules/allocation/alloc_mmap/mmap_mem.cpp b/modules/allocation/alloc_mmap/mmap_mem.cpp
new file mode 100644
index 000000000..e9ea17a53
--- /dev/null
+++ b/modules/allocation/alloc_mmap/mmap_mem.cpp
@@ -0,0 +1,128 @@
+/*************************************************
+* Memory Mapping Allocator Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/mmap_mem.h>
+#include <cstring>
+
+#ifndef _XOPEN_SOURCE
+ #define _XOPEN_SOURCE 500
+#endif
+
+#ifndef _XOPEN_SOURCE_EXTENDED
+ #define _XOPEN_SOURCE_EXTENDED 1
+#endif
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#ifndef MAP_FAILED
+ #define MAP_FAILED -1
+#endif
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* MemoryMapping_Allocator Exception *
+*************************************************/
+class MemoryMapping_Failed : public Exception
+ {
+ public:
+ MemoryMapping_Failed(const std::string& msg) :
+ Exception("MemoryMapping_Allocator: " + msg) {}
+ };
+
+}
+
+/*************************************************
+* Memory Map a File into Memory *
+*************************************************/
+void* MemoryMapping_Allocator::alloc_block(u32bit n)
+ {
+ class TemporaryFile
+ {
+ public:
+ int get_fd() const { return fd; }
+ const std::string path() const { return filepath; }
+
+ TemporaryFile(const std::string& base)
+ {
+ const std::string path = base + "XXXXXX";
+
+ filepath = new char[path.length() + 1];
+ std::strcpy(filepath, path.c_str());
+
+ mode_t old_umask = ::umask(077);
+ fd = ::mkstemp(filepath);
+ ::umask(old_umask);
+ }
+
+ ~TemporaryFile()
+ {
+ delete[] filepath;
+ if(fd != -1 && ::close(fd) == -1)
+ throw MemoryMapping_Failed("Could not close file");
+ }
+ private:
+ int fd;
+ char* filepath;
+ };
+
+ TemporaryFile file("/tmp/botan_");
+
+ if(file.get_fd() == -1)
+ throw MemoryMapping_Failed("Could not create file");
+
+ if(::unlink(file.path().c_str()))
+ throw MemoryMapping_Failed("Could not unlink file '" + file.path() + "'");
+
+ ::lseek(file.get_fd(), n-1, SEEK_SET);
+ if(::write(file.get_fd(), "\0", 1) != 1)
+ throw MemoryMapping_Failed("Could not write to file");
+
+#ifndef MAP_NOSYNC
+ #define MAP_NOSYNC 0
+#endif
+
+ void* ptr = ::mmap(0, n,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_NOSYNC,
+ file.get_fd(), 0);
+
+ if(ptr == static_cast<void*>(MAP_FAILED))
+ throw MemoryMapping_Failed("Could not map file");
+
+ return ptr;
+ }
+
+/*************************************************
+* Remove a Memory Mapping *
+*************************************************/
+void MemoryMapping_Allocator::dealloc_block(void* ptr, u32bit n)
+ {
+ if(ptr == 0)
+ return;
+
+ const byte PATTERNS[] = { 0x00, 0xFF, 0xAA, 0x55, 0x73, 0x8C, 0x5F, 0xA0,
+ 0x6E, 0x91, 0x30, 0xCF, 0xD3, 0x2C, 0xAC, 0x00 };
+
+ for(u32bit j = 0; j != sizeof(PATTERNS); j++)
+ {
+ std::memset(ptr, PATTERNS[j], n);
+
+ if(::msync(ptr, n, MS_SYNC))
+ throw MemoryMapping_Failed("Sync operation failed");
+ }
+
+ if(::munmap(ptr, n))
+ throw MemoryMapping_Failed("Could not unmap file");
+ }
+
+}