diff options
author | lloyd <[email protected]> | 2008-09-28 15:34:09 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2008-09-28 15:34:09 +0000 |
commit | ea32d18231b9c6c5c84b3754c4249170d3b4e4c0 (patch) | |
tree | cc179337d0594ed105768011722b9dbae105e07a /modules/allocation/alloc_mmap/mmap_mem.cpp | |
parent | b841401e095cfc1aa0708689d7920eb95ece71af (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.cpp | 128 |
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"); + } + +} |