1 //===- Unix/MappedFile.cpp - Unix MappedFile Implementation -----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by Reid Spencer and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file provides the generic Unix implementation of the MappedFile concept.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 //=== WARNING: Implementation here must contain only generic UNIX code that
16 //=== is guaranteed to work on *all* UNIX variants.
17 //===----------------------------------------------------------------------===//
20 #include "llvm/System/Process.h"
26 #ifdef HAVE_SYS_MMAN_H
30 #ifdef HAVE_SYS_STAT_H
37 struct sys::MappedFileInfo {
42 void MappedFile::initialize() {
44 info_ = new MappedFileInfo;
46 if (options_&READ_ACCESS)
47 if (options_&WRITE_ACCESS)
51 else if (options_&WRITE_ACCESS)
53 info_->fd_ = ::open(path_.c_str(),mode);
57 ThrowErrno(std::string("Can't open file: ") + path_.toString());
60 if(::fstat(info_->fd_, &info_->sbuf_) < 0) {
64 ThrowErrno(std::string("Can't stat file: ") + path_.toString());
67 throw std::string("Can't open file: ") + path_.toString();
71 void MappedFile::terminate() {
72 assert(info_ && "MappedFile not initialized");
79 void MappedFile::unmap() {
80 assert(info_ && "MappedFile not initialized");
82 if (options_ & WRITE_ACCESS)
83 ::msync(base_, info_->sbuf_.st_size, MS_SYNC);
84 ::munmap(base_, info_->sbuf_.st_size);
88 void* MappedFile::map() {
89 assert(info_ && "MappedFile not initialized");
100 if (options_ & READ_ACCESS)
102 if (options_ & WRITE_ACCESS)
104 if (options_ & EXEC_ACCESS)
106 if (options_ & SHARED_MAPPING)
109 flags |= MAP_PRIVATE;
111 size_t map_size = ((info_->sbuf_.st_size / Process::GetPageSize())+1) *
112 Process::GetPageSize();
114 base_ = ::mmap(0, map_size, prot, flags, info_->fd_, 0);
115 if (base_ == MAP_FAILED)
116 ThrowErrno(std::string("Can't map file:") + path_.toString());
121 size_t MappedFile::size() const {
122 assert(info_ && "MappedFile not initialized");
123 return info_->sbuf_.st_size;
126 void MappedFile::size(size_t new_size) {
127 assert(info_ && "MappedFile not initialized");
129 // Take the mapping out of memory
132 // Adjust the current size to a page boundary
133 size_t cur_size = ((info_->sbuf_.st_size / Process::GetPageSize())+1) *
134 Process::GetPageSize();
136 // Adjust the new_size to a page boundary
137 new_size = ((new_size / Process::GetPageSize())+1) *
138 Process::GetPageSize();
140 // If the file needs to be extended
141 if (new_size > cur_size) {
142 // Ensure we can allocate at least the idodes necessary to handle the
143 // file size requested.
144 ::lseek(info_->fd_, new_size, SEEK_SET);
145 ::write(info_->fd_, "\0", 1);
148 // Seek to current end of file.
154 // vim: sw=2 smartindent smarttab tw=80 autoindent expandtab