using namespace sys;
struct sys::MappedFileInfo {
- int fd_;
- struct stat sbuf_;
+ int FD;
+ off_t Size;
};
-void MappedFile::initialize() {
- if (path_.exists()) {
- info_ = new MappedFileInfo;
- int mode = 0;
- if (options_&READ_ACCESS)
- if (options_&WRITE_ACCESS)
- mode = O_RDWR;
- else
- mode = O_RDONLY;
- else if (options_&WRITE_ACCESS)
- mode = O_WRONLY;
- info_->fd_ = ::open(path_.c_str(),mode);
-
- if (info_->fd_ < 0) {
- delete info_;
- info_ = 0;
- ThrowErrno(std::string("Can't open file: ") + path_.toString());
- }
- struct stat sbuf;
- if(::fstat(info_->fd_, &info_->sbuf_) < 0) {
- ::close(info_->fd_);
- delete info_;
- info_ = 0;
- ThrowErrno(std::string("Can't stat file: ") + path_.toString());
- }
- } else {
- 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)
+ mode = O_RDWR;
+ else
+ mode = O_RDONLY;
+ else if (options_ & WRITE_ACCESS)
+ mode = O_WRONLY;
+
+ int FD = ::open(path_.c_str(), mode);
+ 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);
+ return true;
}
+ info_ = new MappedFileInfo;
+ 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) {
+bool MappedFile::size(size_t new_size, std::string* ErrMsg) {
assert(info_ && "MappedFile not initialized");
// Take the mapping out of memory
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);
+ if ((off_t)-1 == ::lseek(info_->FD, new_size, SEEK_SET))
+ return MakeErrMsg(ErrMsg, "Can't lseek: ");
+ if (-1 == ::write(info_->FD, "\0", 1))
+ return MakeErrMsg(ErrMsg, "Can't write: ");
}
- // Seek to current end of file.
- this->map();
+ // Put the mapping back into memory.
+ return this->map(ErrMsg);
}
}