mirror of
https://github.com/ksherlock/profuse.git
synced 2026-03-11 11:41:47 +00:00
git-svn-id: https://profuse.googlecode.com/svn/branches/v2@214 aa027e90-d47c-11dd-86d7-074df07e0730
This commit is contained in:
@@ -13,47 +13,83 @@ MappedFile::MappedFile()
|
||||
{
|
||||
_length = -1;
|
||||
_address = MAP_FAILED;
|
||||
_readOnly = true;
|
||||
}
|
||||
|
||||
MappedFile::MappedFile(MappedFile &mf)
|
||||
{
|
||||
_address = mf._address;
|
||||
_length = mf._length;
|
||||
_readOnly = mf._readOnly;
|
||||
|
||||
mf._address = MAP_FAILED;
|
||||
mf._length = -1;
|
||||
mf._readOnly = true;
|
||||
}
|
||||
|
||||
MappedFile::MappedFile(File f, bool readOnly)
|
||||
MappedFile::MappedFile(const File &f, bool readOnly, size_t size)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "MappedFile::MappedFile"
|
||||
_length = -1;
|
||||
_address = MAP_FAILED;
|
||||
_readOnly = readOnly;
|
||||
|
||||
init(f, readOnly, size);
|
||||
}
|
||||
|
||||
|
||||
MappedFile::MappedFile(const char *name, bool readOnly)
|
||||
{
|
||||
File f(name, readOnly);
|
||||
|
||||
_length = -1;
|
||||
_address = MAP_FAILED;
|
||||
_readOnly = readOnly;
|
||||
|
||||
init(f, readOnly, -1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
MappedFile::~MappedFile()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MappedFile::init(const File &f, bool readOnly, size_t size)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "MappedFile::init"
|
||||
|
||||
struct stat st;
|
||||
|
||||
// close enough
|
||||
if (f.fd() < 0)
|
||||
throw POSIXException( __METHOD__, EBADF);
|
||||
|
||||
|
||||
if (::fstat(f.fd(), &st) != 0)
|
||||
throw POSIXException(__METHOD__ ": fstat", errno);
|
||||
|
||||
if (!S_ISREG(st.st_mode))
|
||||
throw POSIXException(__METHOD__, ENODEV);
|
||||
|
||||
if (size <= 0)
|
||||
{
|
||||
if (::fstat(f.fd(), &st) != 0)
|
||||
throw POSIXException(__METHOD__ ": fstat", errno);
|
||||
|
||||
_length = st.st_size;
|
||||
if (!S_ISREG(st.st_mode))
|
||||
throw POSIXException(__METHOD__, ENODEV);
|
||||
|
||||
size = st.st_size;
|
||||
}
|
||||
|
||||
_length = size;
|
||||
_address = ::mmap(0, _length,
|
||||
readOnly ? PROT_READ : PROT_READ | PROT_WRITE,
|
||||
MAP_FILE | MAP_SHARED, f.fd(), 0);
|
||||
|
||||
readOnly ? PROT_READ : PROT_READ | PROT_WRITE,
|
||||
MAP_FILE | MAP_SHARED, f.fd(), 0);
|
||||
|
||||
if (_address == MAP_FAILED)
|
||||
throw POSIXException(__METHOD__ ": mmap", errno);
|
||||
}
|
||||
|
||||
MappedFile::~MappedFile()
|
||||
{
|
||||
close();
|
||||
|
||||
_readOnly = readOnly;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +106,7 @@ void MappedFile::close()
|
||||
|
||||
_address = MAP_FAILED;
|
||||
_length = -1;
|
||||
_readOnly = true;
|
||||
|
||||
if (::munmap(address, length) != 0)
|
||||
throw POSIXException(__METHOD__ ": munmap", errno);
|
||||
@@ -93,13 +130,39 @@ void MappedFile::adopt(MappedFile &mf)
|
||||
close();
|
||||
_address = mf._address;
|
||||
_length = mf._length;
|
||||
_readOnly = mf._readOnly;
|
||||
|
||||
mf._address = MAP_FAILED;
|
||||
mf._length = -1;
|
||||
mf._readOnly = true;
|
||||
}
|
||||
|
||||
void MappedFile::swap(MappedFile &mf)
|
||||
{
|
||||
std::swap(_address, mf._address);
|
||||
std::swap(_length, mf._length);
|
||||
std::swap(_readOnly, mf._readOnly);
|
||||
}
|
||||
|
||||
|
||||
static MappedFile *Create(const char *name, size_t size)
|
||||
{
|
||||
#undef __METHOD__
|
||||
#define __METHOD__ "MappedFile::Create"
|
||||
|
||||
File fd(::open(name, O_CREAT | O_TRUNC | O_RDWR, 0644));
|
||||
|
||||
if (!fd.isValid())
|
||||
{
|
||||
throw POSIXException(__METHOD__ ": Unable to create file.", errno);
|
||||
}
|
||||
|
||||
// TODO -- is ftruncate portable?
|
||||
if (::ftruncate(fd.fd(), size) < 0)
|
||||
{
|
||||
// TODO -- unlink?
|
||||
throw POSIXException(__METHOD__ ": Unable to truncate file.", errno);
|
||||
}
|
||||
|
||||
return new MappedFile(fd, false, size);
|
||||
}
|
||||
Reference in New Issue
Block a user