29 #include <sys/types.h>
39 #define ERROR(msg) throw MemoryMapError(msg)
45 const int MemoryMap::pagesize = getpagesize();
47 void MemoryMap::pagesizealign(ostream &out)
49 size_t at = out.tellp();
50 size_t offs = at % pagesize;
51 if(offs) { out.seekp(pagesize - offs, ios::cur); }
54 void MemoryMap::pagesizealign(istream &in)
56 size_t at = in.tellg();
57 size_t offs = at % pagesize;
58 if(offs) { in.seekg(pagesize - offs, ios::cur); }
61 void MemoryMap::open(
const std::string &fn,
size_t length_,
size_t offset,
int mode,
int mapstyle)
63 if(offset > 0 && (offset % pagesize)) { ERROR(
"Invalid offset requested for memory mapped area - not a multiple of pagesize (" +
str(pagesize) +
")"); }
67 if(mode & rw) { flags |= O_RDWR | O_CREAT; }
68 else if(mode & ro) { flags |= O_RDONLY; }
69 else if(mode & wo) { flags |= O_WRONLY | O_CREAT; }
70 else ERROR(
"Invalid mode parameter - mode needs to include ro, wo or rw");
72 int create_mode = 00600;
74 int fd = ::open(fn.c_str(), flags, create_mode);
79 ERROR(
string(
"Error opening file [") + fn +
"]");
82 if(length_ == 0 && !(flags & O_WRONLY))
86 length_ = buf.st_size;
91 open(fd, length_, offset, mode, mapstyle,
true);
94 void MemoryMap::open(
int fd_,
size_t length_,
size_t offset,
int prot,
int mapstyle,
bool closefd_)
105 if(buf.st_size < offset + length)
107 if(!(prot & PROT_WRITE))
110 ERROR(
string(
"A read-only file is smaller than the length requested to be memory mapped"));
114 lseek(fd, offset + length - 1, SEEK_SET);
119 map = mmap(0, length, prot, mapstyle, fd, offset);
120 if(map == MAP_FAILED)
124 ERROR(
string(
"mmap failed:") + strerror(errno) +
" {filename:" + filename +
",length:" +
str(length) +
", offset:" +
str(offset)+
"}");
132 msync(map, length, MS_SYNC);
135 MemoryMap::MemoryMap()
136 : filename(
""), fd(0), map(NULL), length(0), closefd(true)
140 MemoryMap::MemoryMap(
const std::string &fn,
size_t length_,
size_t offset,
int mode,
int mapstyle)
141 : filename(fn), fd(0), map(NULL), length(length_)
143 open(fn, length, offset, mode, mapstyle);
146 void MemoryMap::close()
150 if(munmap(map, length) == -1) { ERROR(
string(
"Error unmapping file [") + filename +
"]"); }
154 if(closefd && fd != 0)
156 if(::close(fd) == -1) { ERROR(
string(
"Error closing file [") + filename +
"]"); }