📄 mmap_mem.cpp
字号:
/************************************************** Memory Mapping Allocator Source File ** (C) 1999-2002 The Botan Project **************************************************/#ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 500#endif#ifndef _XOPEN_SOURCE_EXTENDED #define _XOPEN_SOURCE_EXTENDED 1#endif#include <botan/mmap_mem.h>#include <botan/exceptn.h>#include <botan/util.h>#include <cstring>#include <sys/types.h>#include <sys/mman.h>#include <sys/stat.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>namespace Botan {/************************************************** Constructor **************************************************/MemoryMapping_Allocator::MemoryMapping_Allocator(const std::string& dir, bool careful) : ManagedAllocator(true, 64*1024), paranoid(careful), path(temp_dir(dir) + "/botan_XXXXXX") { static const u32bit CACHE_SIZE = 7; cache.resize(CACHE_SIZE); for(u32bit j = 0; j != cache.size(); j++) { cache[j].length = 64*1024; cache[j].buf = mmap_block(cache[j].length); cache[j].fd = allocated[cache[j].buf].first; allocated.erase(allocated.find(cache[j].buf)); } }/************************************************** Destructor **************************************************/MemoryMapping_Allocator::~MemoryMapping_Allocator() { for(u32bit j = 0; j != cache.size(); j++) munmap_block(cache[j].buf, cache[j].length, cache[j].fd); }/************************************************** Return the name of a good temporary directory **************************************************/std::string MemoryMapping_Allocator::temp_dir(const std::string& dir) const { if(dir != "") return dir; return "/tmp"; }/************************************************** Allocation **************************************************/void* MemoryMapping_Allocator::alloc_block(u32bit n) const { for(u32bit j = 0; j != cache.size(); j++) { if(cache[j].length == n && cache[j].buf != 0) { void* ptr = cache[j].buf; allocated[ptr] = std::pair<int, u32bit>(cache[j].fd, cache[j].length); cache[j].buf = 0; cache[j].length = 0; cache[j].fd = 0; return ptr; } } void* ptr = mmap_block(n); return ptr; }/************************************************** Deallocation **************************************************/void MemoryMapping_Allocator::dealloc_block(void* ptr, u32bit n) const { if(ptr == 0) return; if(allocated.find(ptr) == allocated.end()) throw Exception("MemoryMapping_Allocator: pointer not found"); if(allocated[ptr].second != n) throw Exception("MemoryMapping_Allocator: bad length for memory block"); for(u32bit j = 0; j != cache.size(); j++) if(cache[j].buf == 0 && n % 1024 == 0) { cache[j].buf = ptr; cache[j].length = n; cache[j].fd = allocated[ptr].first; allocated.erase(ptr); return; } munmap_block(ptr, n, allocated[ptr].first); allocated.erase(ptr); }/************************************************** Memory Map a File into Memory **************************************************/void* MemoryMapping_Allocator::mmap_block(u32bit n) const { char* filepath = new char[path.length() + 1]; std::strcpy(filepath, path.c_str()); mode_t old_umask = umask(077); int file = mkstemp(filepath); if(file == -1) throw Exception("MemoryMapping_Allocator: Could not create file"); if(unlink(filepath)) throw Exception("MemoryMapping_Allocator: Could not unlink file " + std::string(filepath)); delete[] filepath; umask(old_umask); lseek(file, n-1, SEEK_SET); if(write(file, "\0", 1) != 1) throw Exception("MemoryMapping_Allocator: Could not write to file"); void* ptr = mmap(0, n, PROT_READ | PROT_WRITE, MAP_SHARED, file, 0); if(ptr == (void*)MAP_FAILED) throw Exception("MemoryMapping_Allocator: Could not map file"); allocated[ptr] = std::make_pair<int, u32bit>(file, n); return ptr; }/************************************************** Remove a Memory Map **************************************************/void MemoryMapping_Allocator::munmap_block(void* ptr, u32bit n, int fd) const { static const u32bit PATTERN_COUNT = 12; static const byte PATTERNS[PATTERN_COUNT] = { 0x22, 0xFF, 0xAA, 0x55, 0x11, 0xEE, 0xDE, 0xAD, 0x77, 0x88, 0x33, 0xCC }; const u32bit OVERWRITE_PASSES = (paranoid ? 15 : 7); if(ptr == 0) return; for(u32bit j = 0; j != OVERWRITE_PASSES; j++) { std::memset(ptr, PATTERNS[j % PATTERN_COUNT], n); if(msync(ptr, n, MS_SYNC)) throw Exception("MemoryMapping_Allocator: Sync operation failed"); } std::memset(ptr, 0, n); if(msync(ptr, n, MS_SYNC)) throw Exception("MemoryMapping_Allocator: Sync operation failed"); if(munmap(ptr, n)) throw Exception("MemoryMapping_Allocator: Could not unmap file"); if(close(fd)) throw Exception("MemoryMapping_Allocator: Could not close file"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -