CernVM-FS  2.13.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 
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 "util/logging.h"
23 #include "util/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)
73  "failed to mmap %s (file size: %ld) "
74  "(errno: %d)",
75  file_path_.c_str(), filesize.st_size, errno);
76  close(fd);
77  return false;
78  }
79  }
80 
81  // save results
82  mapped_file_ = static_cast<unsigned char *>(mapping);
83  file_descriptor_ = fd;
84  mapped_size_ = filesize.st_size;
85  mapped_ = true;
86  LogCvmfs(kLogUtility, kLogVerboseMsg, "mmap'ed %s", file_path_.c_str());
87  return true;
88 }
89 
91  assert(mapped_);
92 
93  if (mapped_file_ == NULL) {
94  return;
95  }
96 
97  // unmap the previously mapped file
98  if ((munmap(static_cast<void *>(mapped_file_), mapped_size_) != 0)
99  || (close(file_descriptor_) != 0)) {
100  LogCvmfs(kLogUtility, kLogStderr, "failed to unmap %s", file_path_.c_str());
101  const bool munmap_failed = false;
102  assert(munmap_failed);
103  }
104 
105  // reset (resettable) data
106  mapped_file_ = NULL;
107  file_descriptor_ = -1;
108  mapped_size_ = 0;
109  mapped_ = false;
110  LogCvmfs(kLogUtility, kLogVerboseMsg, "munmap'ed %s", file_path_.c_str());
111 }
112 
113 #ifdef CVMFS_NAMESPACE_GUARD
114 } // namespace CVMFS_NAMESPACE_GUARD
115 #endif
MemoryMappedFile(const std::string &file_path)
Definition: mmap_file.cc:32
struct stat64 platform_stat64
unsigned char * mapped_file_
Definition: mmap_file.h:41
assert((mem||(size==0))&&"Out Of Memory")
const std::string file_path_
Definition: mmap_file.h:39
size_t mapped_size_
Definition: mmap_file.h:42
bool IsMapped() const
Definition: mmap_file.h:36
int file_descriptor_
Definition: mmap_file.h:40
const int kLogVerboseMsg
int platform_fstat(int filedes, platform_stat64 *buf)
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)
Definition: logging.cc:545