Directory: | cvmfs/ |
---|---|
File: | cvmfs/util/mmap_file.cc |
Date: | 2025-06-22 02:36:02 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 33 | 49 | 67.3% |
Branches: | 13 | 39 | 33.3% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * This file is part of the CernVM File System. | ||
3 | * | ||
4 | * Some common functions. | ||
5 | */ | ||
6 | |||
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 | 3578 | MemoryMappedFile::MemoryMappedFile(const std::string &file_path) | |
33 | 3578 | : file_path_(file_path) | |
34 | 3578 | , file_descriptor_(-1) | |
35 | 3578 | , mapped_file_(NULL) | |
36 | 3578 | , mapped_size_(0) | |
37 | 3578 | , mapped_(false) { } | |
38 | |||
39 | 7154 | MemoryMappedFile::~MemoryMappedFile() { | |
40 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3577 times.
|
3577 | if (IsMapped()) { |
41 | ✗ | Unmap(); | |
42 | } | ||
43 | 3577 | } | |
44 | |||
45 | 3577 | bool MemoryMappedFile::Map() { | |
46 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3577 times.
|
3577 | assert(!mapped_); |
47 | |||
48 | // open the file | ||
49 | int fd; | ||
50 |
2/4✓ Branch 2 taken 3577 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3577 times.
|
3577 | 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 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3577 times.
|
3577 | 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 | 3577 | void *mapping = NULL; | |
68 |
1/2✓ Branch 0 taken 3577 times.
✗ Branch 1 not taken.
|
3577 | if (filesize.st_size > 0) { |
69 | // map the given file into memory | ||
70 | 3577 | mapping = mmap(NULL, filesize.st_size, PROT_READ, MAP_PRIVATE, fd, 0); | |
71 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3577 times.
|
3577 | if (mapping == MAP_FAILED) { // NOLINT(performance-no-int-to-ptr) |
72 | ✗ | LogCvmfs(kLogUtility, kLogStderr, | |
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 | 3577 | mapped_file_ = static_cast<unsigned char *>(mapping); | |
83 | 3577 | file_descriptor_ = fd; | |
84 | 3577 | mapped_size_ = filesize.st_size; | |
85 | 3577 | mapped_ = true; | |
86 |
1/2✓ Branch 2 taken 3577 times.
✗ Branch 3 not taken.
|
3577 | LogCvmfs(kLogUtility, kLogVerboseMsg, "mmap'ed %s", file_path_.c_str()); |
87 | 3577 | return true; | |
88 | } | ||
89 | |||
90 | 3577 | void MemoryMappedFile::Unmap() { | |
91 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3577 times.
|
3577 | assert(mapped_); |
92 | |||
93 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3577 times.
|
3577 | if (mapped_file_ == NULL) { |
94 | ✗ | return; | |
95 | } | ||
96 | |||
97 | // unmap the previously mapped file | ||
98 | 3577 | if ((munmap(static_cast<void *>(mapped_file_), mapped_size_) != 0) | |
99 |
3/6✓ Branch 0 taken 3577 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3577 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3577 times.
|
3577 | || (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 | 3577 | mapped_file_ = NULL; | |
107 | 3577 | file_descriptor_ = -1; | |
108 | 3577 | mapped_size_ = 0; | |
109 | 3577 | mapped_ = false; | |
110 | 3577 | LogCvmfs(kLogUtility, kLogVerboseMsg, "munmap'ed %s", file_path_.c_str()); | |
111 | } | ||
112 | |||
113 | #ifdef CVMFS_NAMESPACE_GUARD | ||
114 | } // namespace CVMFS_NAMESPACE_GUARD | ||
115 | #endif | ||
116 |