Directory: | cvmfs/ |
---|---|
File: | cvmfs/util/mmap_file.cc |
Date: | 2025-02-09 02:34:19 |
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 | 256 | MemoryMappedFile::MemoryMappedFile(const std::string &file_path) : | |
33 | 256 | file_path_(file_path), | |
34 | 256 | file_descriptor_(-1), | |
35 | 256 | mapped_file_(NULL), | |
36 | 256 | mapped_size_(0), | |
37 | 256 | mapped_(false) {} | |
38 | |||
39 | 512 | MemoryMappedFile::~MemoryMappedFile() { | |
40 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 256 times.
|
256 | if (IsMapped()) { |
41 | ✗ | Unmap(); | |
42 | } | ||
43 | 256 | } | |
44 | |||
45 | 256 | bool MemoryMappedFile::Map() { | |
46 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 256 times.
|
256 | assert(!mapped_); |
47 | |||
48 | // open the file | ||
49 | int fd; | ||
50 |
2/4✓ Branch 2 taken 256 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 256 times.
|
256 | 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 256 times.
|
256 | 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 | 256 | void *mapping = NULL; | |
68 |
1/2✓ Branch 0 taken 256 times.
✗ Branch 1 not taken.
|
256 | if (filesize.st_size > 0) { |
69 | // map the given file into memory | ||
70 | 256 | mapping = mmap(NULL, filesize.st_size, PROT_READ, MAP_PRIVATE, fd, 0); | |
71 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 256 times.
|
256 | if (mapping == MAP_FAILED) { // NOLINT(performance-no-int-to-ptr) |
72 | ✗ | LogCvmfs(kLogUtility, kLogStderr, "failed to mmap %s (file size: %ld) " | |
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 | 256 | mapped_file_ = static_cast<unsigned char*>(mapping); | |
84 | 256 | file_descriptor_ = fd; | |
85 | 256 | mapped_size_ = filesize.st_size; | |
86 | 256 | mapped_ = true; | |
87 |
1/2✓ Branch 2 taken 256 times.
✗ Branch 3 not taken.
|
256 | LogCvmfs(kLogUtility, kLogVerboseMsg, "mmap'ed %s", file_path_.c_str()); |
88 | 256 | return true; | |
89 | } | ||
90 | |||
91 | 256 | void MemoryMappedFile::Unmap() { | |
92 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 256 times.
|
256 | assert(mapped_); |
93 | |||
94 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 256 times.
|
256 | if (mapped_file_ == NULL) { |
95 | ✗ | return; | |
96 | } | ||
97 | |||
98 | // unmap the previously mapped file | ||
99 |
2/4✓ Branch 1 taken 256 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 256 times.
|
512 | if ((munmap(static_cast<void*>(mapped_file_), mapped_size_) != 0) || |
100 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 256 times.
|
256 | (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 | 256 | mapped_file_ = NULL; | |
109 | 256 | file_descriptor_ = -1; | |
110 | 256 | mapped_size_ = 0; | |
111 | 256 | mapped_ = false; | |
112 | 256 | 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 |