For PR797:
[oota-llvm.git] / lib / System / Unix / MappedFile.inc
index 7e03cd15a819a9a6e46d8fad34dd4cdac80b8235..ef959bacab21751710818c8271d3117e3fba3720 100644 (file)
 //===          is guaranteed to work on *all* UNIX variants.
 //===----------------------------------------------------------------------===//
 
-#include "llvm/System/Process.h"
 #include "Unix.h"
+#include "llvm/System/Process.h"
+
+#ifdef HAVE_FCNTL_H
 #include <fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_MMAN_H
 #include <sys/mman.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
 
 namespace llvm {
 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_.get());
-    }
-    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_.get());
-    }
+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;
 }
@@ -68,12 +77,13 @@ void MappedFile::unmap() {
   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;
     int flags = 0;
@@ -95,19 +105,21 @@ void* MappedFile::map() {
       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_.get());
+    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() {
+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) {
@@ -117,7 +129,7 @@ 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
@@ -128,14 +140,13 @@ void MappedFile::size(size_t new_size) {
   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);
 }
 
 }
 
-// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab