CernVM-FS  2.10.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mmap_file.cc
Go to the documentation of this file.
1 
7 #ifndef __STDC_FORMAT_MACROS
8 // NOLINTNEXTLINE
9 #define __STDC_FORMAT_MACROS
10 #endif
11 
12 #include "cvmfs_config.h"
13 #include "mmap_file.h"
14 
15 #include <errno.h>
16 #include <fcntl.h>
17 #include <sys/mman.h>
18 #include <unistd.h>
19 
20 #include <cassert>
21 
22 #include "logging.h"
23 #include "platform.h"
24 
25 using namespace std; // NOLINT
26 
27 #ifdef CVMFS_NAMESPACE_GUARD
28 namespace CVMFS_NAMESPACE_GUARD {
29 #endif
30 
31 
32 MemoryMappedFile::MemoryMappedFile(const std::string &file_path) :
33  file_path_(file_path),
34  file_descriptor_(-1),
35  mapped_file_(NULL),
36  mapped_size_(0),
37  mapped_(false) {}
38 
40  if (IsMapped()) {
41  Unmap();
42  }
43 }
44 
46  assert(!mapped_);
47 
48  // open the file
49  int fd;
50  if ((fd = open(file_path_.c_str(), O_RDONLY, 0)) == -1) {
51  LogCvmfs(kLogUtility, kLogStderr, "failed to open %s (%d)",
52  file_path_.c_str(), errno);
53  return false;
54  }
55 
56  // get file size
57  platform_stat64 filesize;
58  if (platform_fstat(fd, &filesize) != 0) {
59  LogCvmfs(kLogUtility, kLogStderr, "failed to fstat %s (%d)",
60  file_path_.c_str(), errno);
61  close(fd);
62  return false;
63  }
64 
65  // check if the file is empty and 'pretend' that the file is mapped
66  // --> buffer will then look like a buffer without any size...
67  void *mapping = NULL;
68  if (filesize.st_size > 0) {
69  // map the given file into memory
70  mapping = mmap(NULL, filesize.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
71  if (mapping == MAP_FAILED) { // NOLINT(performance-no-int-to-ptr)
72  LogCvmfs(kLogUtility, kLogStderr, "failed to mmap %s (file size: %d) "
73  "(errno: %d)",
74  file_path_.c_str(),
75  filesize.st_size,
76  errno);
77  close(fd);
78  return false;
79  }
80  }
81 
82  // save results
83  mapped_file_ = static_cast<unsigned char*>(mapping);
84  file_descriptor_ = fd;
85  mapped_size_ = filesize.st_size;
86  mapped_ = true;
87  LogCvmfs(kLogUtility, kLogVerboseMsg, "mmap'ed %s", file_path_.c_str());
88  return true;
89 }
90 
92  assert(mapped_);
93 
94  if (mapped_file_ == NULL) {
95  return;
96  }
97 
98  // unmap the previously mapped file
99  if ((munmap(static_cast<void*>(mapped_file_), mapped_size_) != 0) ||
100  (close(file_descriptor_) != 0))
101  {
102  LogCvmfs(kLogUtility, kLogStderr, "failed to unmap %s", file_path_.c_str());
103  const bool munmap_failed = false;
104  assert(munmap_failed);
105  }
106 
107  // reset (resettable) data
108  mapped_file_ = NULL;
109  file_descriptor_ = -1;
110  mapped_size_ = 0;
111  mapped_ = false;
112  LogCvmfs(kLogUtility, kLogVerboseMsg, "munmap'ed %s", file_path_.c_str());
113 }
114 
115 #ifdef CVMFS_NAMESPACE_GUARD
116 } // namespace CVMFS_NAMESPACE_GUARD
117 #endif
#define LogCvmfs(source, mask,...)
Definition: logging.h:20
MemoryMappedFile(const std::string &file_path)
Definition: mmap_file.cc:32
struct stat64 platform_stat64
unsigned char * mapped_file_
Definition: mmap_file.h:40
assert((mem||(size==0))&&"Out Of Memory")
const std::string file_path_
Definition: mmap_file.h:38
size_t mapped_size_
Definition: mmap_file.h:41
bool IsMapped() const
Definition: mmap_file.h:35
int file_descriptor_
Definition: mmap_file.h:39
const int kLogVerboseMsg
int platform_fstat(int filedes, platform_stat64 *buf)