using namespace sys;
struct sys::MappedFileInfo {
- int fd_;
- struct stat sbuf_;
+ int FD;
+ off_t Size;
};
-void MappedFile::initialize() {
- if (!path_.exists())
- throw std::string("Can't open file: ") + path_.toString();
-
+bool MappedFile::initialize(std::string* ErrMsg) {
int mode = 0;
- if (options_&READ_ACCESS)
- if (options_&WRITE_ACCESS)
+ if (options_ & READ_ACCESS)
+ if (options_ & WRITE_ACCESS)
mode = O_RDWR;
else
mode = O_RDONLY;
- else if (options_&WRITE_ACCESS)
+ else if (options_ & WRITE_ACCESS)
mode = O_WRONLY;
int FD = ::open(path_.c_str(), mode);
- if (FD < 0)
- ThrowErrno(std::string("Can't open file: ") + path_.toString());
-
+ if (FD < 0) {
+ MakeErrMsg(ErrMsg, "can't open file '" + path_.toString() + "'");
+ return true;
+ }
struct stat sbuf;
if(::fstat(FD, &sbuf) < 0) {
+ MakeErrMsg(ErrMsg, "can't stat file '"+ path_.toString() + "'");
::close(FD);
- ThrowErrno(std::string("Can't stat file: ") + path_.toString());
+ return true;
}
info_ = new MappedFileInfo;
- info_->fd_ = FD;
- info_->sbuf_ = sbuf;
+ info_->FD = FD;
+ info_->Size = sbuf.st_size;
+ return false;
}
void MappedFile::terminate() {
assert(info_ && "MappedFile not initialized");
- if (info_->fd_ >= 0)
- ::close(info_->fd_);
+ ::close(info_->FD);
delete info_;
info_ = 0;
}
assert(info_ && "MappedFile not initialized");
if (isMapped()) {
if (options_ & WRITE_ACCESS)
- ::msync(base_, info_->sbuf_.st_size, MS_SYNC);
- ::munmap(base_, info_->sbuf_.st_size);
+ ::msync(base_, info_->Size, MS_SYNC);
+ ::munmap(base_, info_->Size);
}
}
-void* MappedFile::map() {
+void* MappedFile::map(std::string* ErrMsg) {
assert(info_ && "MappedFile not initialized");
if (!isMapped()) {
int prot = PROT_NONE;
else
flags |= MAP_PRIVATE;
}
- size_t map_size = ((info_->sbuf_.st_size / Process::GetPageSize())+1) *
+ size_t map_size = ((info_->Size / Process::GetPageSize())+1) *
Process::GetPageSize();
- base_ = ::mmap(0, map_size, prot, flags, info_->fd_, 0);
- if (base_ == MAP_FAILED)
- ThrowErrno(std::string("Can't map file:") + path_.toString());
+ base_ = ::mmap(0, map_size, prot, flags, info_->FD, 0);
+ if (base_ == MAP_FAILED) {
+ MakeErrMsg(ErrMsg, "Can't map file:" + path_.toString());
+ return 0;
+ }
}
return base_;
}
size_t MappedFile::size() const {
assert(info_ && "MappedFile not initialized");
- return info_->sbuf_.st_size;
+ return info_->Size;
}
void MappedFile::size(size_t new_size) {
this->unmap();
// Adjust the current size to a page boundary
- size_t cur_size = ((info_->sbuf_.st_size / Process::GetPageSize())+1) *
+ size_t cur_size = ((info_->Size / Process::GetPageSize())+1) *
Process::GetPageSize();
// Adjust the new_size to a page boundary
if (new_size > cur_size) {
// Ensure we can allocate at least the idodes necessary to handle the
// file size requested.
- ::lseek(info_->fd_, new_size, SEEK_SET);
- ::write(info_->fd_, "\0", 1);
+ ::lseek(info_->FD, new_size, SEEK_SET);
+ ::write(info_->FD, "\0", 1);
}
- // Seek to current end of file.
- this->map();
+ // Put the mapping back into memory.
+ this->map(0);
}
}