Directory: | cvmfs/ |
---|---|
File: | cvmfs/util/mmap_file.cc |
Date: | 2025-07-06 02:35:01 |
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 <cstddef> | ||
16 | #include <errno.h> | ||
17 | #include <fcntl.h> | ||
18 | #include <sys/mman.h> | ||
19 | #include <unistd.h> | ||
20 | #include <string> | ||
21 | |||
22 | #include <cassert> | ||
23 | |||
24 | #include "util/logging.h" | ||
25 | #include "util/platform.h" | ||
26 | |||
27 | using namespace std; // NOLINT | ||
28 | |||
29 | #ifdef CVMFS_NAMESPACE_GUARD | ||
30 | namespace CVMFS_NAMESPACE_GUARD { | ||
31 | #endif | ||
32 | |||
33 | |||
34 | 7659 | MemoryMappedFile::MemoryMappedFile(const std::string &file_path) | |
35 | 7659 | : file_path_(file_path) | |
36 | 7659 | , file_descriptor_(-1) | |
37 | 7659 | , mapped_file_(NULL) | |
38 | 7659 | , mapped_size_(0) | |
39 | 7659 | , mapped_(false) { } | |
40 | |||
41 | 15316 | MemoryMappedFile::~MemoryMappedFile() { | |
42 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7658 times.
|
7658 | if (IsMapped()) { |
43 | ✗ | Unmap(); | |
44 | } | ||
45 | 7658 | } | |
46 | |||
47 | 7658 | bool MemoryMappedFile::Map() { | |
48 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7658 times.
|
7658 | assert(!mapped_); |
49 | |||
50 | // open the file | ||
51 | int fd; | ||
52 |
2/4✓ Branch 2 taken 7658 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 7658 times.
|
7658 | if ((fd = open(file_path_.c_str(), O_RDONLY, 0)) == -1) { |
53 | ✗ | LogCvmfs(kLogUtility, kLogStderr, "failed to open %s (%d)", | |
54 | ✗ | file_path_.c_str(), errno); | |
55 | ✗ | return false; | |
56 | } | ||
57 | |||
58 | // get file size | ||
59 | platform_stat64 filesize; | ||
60 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7658 times.
|
7658 | if (platform_fstat(fd, &filesize) != 0) { |
61 | ✗ | LogCvmfs(kLogUtility, kLogStderr, "failed to fstat %s (%d)", | |
62 | ✗ | file_path_.c_str(), errno); | |
63 | ✗ | close(fd); | |
64 | ✗ | return false; | |
65 | } | ||
66 | |||
67 | // check if the file is empty and 'pretend' that the file is mapped | ||
68 | // --> buffer will then look like a buffer without any size... | ||
69 | 7658 | void *mapping = NULL; | |
70 |
1/2✓ Branch 0 taken 7658 times.
✗ Branch 1 not taken.
|
7658 | if (filesize.st_size > 0) { |
71 | // map the given file into memory | ||
72 | 7658 | mapping = mmap(NULL, filesize.st_size, PROT_READ, MAP_PRIVATE, fd, 0); | |
73 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7658 times.
|
7658 | if (mapping == MAP_FAILED) { // NOLINT(performance-no-int-to-ptr) |
74 | ✗ | LogCvmfs(kLogUtility, kLogStderr, | |
75 | "failed to mmap %s (file size: %ld) " | ||
76 | "(errno: %d)", | ||
77 | ✗ | file_path_.c_str(), filesize.st_size, errno); | |
78 | ✗ | close(fd); | |
79 | ✗ | return false; | |
80 | } | ||
81 | } | ||
82 | |||
83 | // save results | ||
84 | 7658 | mapped_file_ = static_cast<unsigned char *>(mapping); | |
85 | 7658 | file_descriptor_ = fd; | |
86 | 7658 | mapped_size_ = filesize.st_size; | |
87 | 7658 | mapped_ = true; | |
88 |
1/2✓ Branch 2 taken 7658 times.
✗ Branch 3 not taken.
|
7658 | LogCvmfs(kLogUtility, kLogVerboseMsg, "mmap'ed %s", file_path_.c_str()); |
89 | 7658 | return true; | |
90 | } | ||
91 | |||
92 | 7658 | void MemoryMappedFile::Unmap() { | |
93 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7658 times.
|
7658 | assert(mapped_); |
94 | |||
95 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7658 times.
|
7658 | if (mapped_file_ == NULL) { |
96 | ✗ | return; | |
97 | } | ||
98 | |||
99 | // unmap the previously mapped file | ||
100 | 7658 | if ((munmap(static_cast<void *>(mapped_file_), mapped_size_) != 0) | |
101 |
3/6✓ Branch 0 taken 7658 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 7658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7658 times.
|
7658 | || (close(file_descriptor_) != 0)) { |
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 | 7658 | mapped_file_ = NULL; | |
109 | 7658 | file_descriptor_ = -1; | |
110 | 7658 | mapped_size_ = 0; | |
111 | 7658 | mapped_ = false; | |
112 | 7658 | LogCvmfs(kLogUtility, kLogVerboseMsg, "munmap'ed %s", file_path_.c_str()); | |
113 | } | ||
114 | |||
115 | #ifdef CVMFS_NAMESPACE_GUARD | ||
116 | } // namespace CVMFS_NAMESPACE_GUARD | ||
117 | #endif | ||
118 |