#include <sys/stat.h>
#include <sys/time.h>
#include <thread>
+#include <optional>
using namespace std;
};
/* Path to mountinfo */
-static const char *mountinfo_path;
-atomic<bool> mountinfo_updated{ false };
+static atomic<bool> mountinfo_updated{ false };
-multimap<pair<int, int>, mount> mount_entries; // Keyed by device major/minor.
+// Keyed by device major/minor.
+using MountEntries = multimap<pair<int, int>, mount>;
/* Read a line from F.
Return a string, or empty string on error. */
}
/* Parse a space-delimited entry in STR, decode octal escapes, write it to
- DEST (allocated from mount_string_obstack) if it is not nullptr.
- Return 0 if OK, -1 on error. */
+ DEST if it is not nullptr. Return 0 if OK, -1 on error. */
static int parse_mount_string(string *dest, const char **str)
{
const char *src = *str;
/* Read mount information from mountinfo_path, update mount_entries and
num_mount_entries.
- Return 0 if OK, -1 on error. */
-static int read_mount_entries(void)
+ Return std::nullopt on error. */
+static optional<MountEntries> read_mount_entries(void)
{
- FILE *f = fopen(mountinfo_path, "r");
+ FILE *f = fopen(MOUNTINFO_PATH, "r");
if (f == nullptr) {
- return -1;
+ return {};
}
- mount_entries.clear();
+ MountEntries mount_entries;
mount me;
while (read_mount_entry(f, &me)) {
if (conf_debug_pruning) {
- /* This is debugging output, don't mark anything for translation */
fprintf(stderr,
" `%s' (%d on %d) is `%s' of `%s' (%u:%u), type `%s'\n",
me.mount_point.c_str(), me.id, me.parent_id, me.root.c_str(), me.source.c_str(),
mount_entries.emplace(make_pair(me.dev_major, me.dev_minor), me);
}
fclose(f);
- return 0;
+ return mount_entries;
}
/* Bind mount path list maintenace and top-level interface. */
static void rebuild_bind_mount_paths(void)
{
if (conf_debug_pruning) {
- /* This is debugging output, don't mark anything for translation */
fprintf(stderr, "Rebuilding bind_mount_paths:\n");
}
- if (read_mount_entries() != 0) {
+ optional<MountEntries> mount_entries = read_mount_entries();
+ if (!mount_entries.has_value()) {
return;
}
if (conf_debug_pruning) {
- /* This is debugging output, don't mark anything for translation */
fprintf(stderr, "Matching bind_mount_paths:\n");
}
bind_mount_paths.clear();
- for (const auto &[dev_id, me] : mount_entries) {
- const auto &[first, second] = mount_entries.equal_range(make_pair(me.dev_major, me.dev_minor));
+ for (const auto &[dev_id, me] : *mount_entries) {
+ const auto &[first, second] = mount_entries->equal_range(make_pair(me.dev_major, me.dev_minor));
for (auto it = first; it != second; ++it) {
const mount &other = it->second;
if (other.id == me.id) {
// If there are two that are equal, prefer the one with lowest ID.
if (me.root.size() > other.root.size() && me.root.find(other.root) == 0) {
if (conf_debug_pruning) {
- /* This is debugging output, don't mark anything for translation */
fprintf(stderr, " => adding `%s' (root `%s' is a child of `%s', mounted on `%s')\n",
me.mount_point.c_str(), me.root.c_str(), other.root.c_str(), other.mount_point.c_str());
}
}
if (me.root == other.root && me.id > other.id) {
if (conf_debug_pruning) {
- /* This is debugging output, don't mark anything for translation */
fprintf(stderr, " => adding `%s' (duplicate of mount point `%s')\n",
me.mount_point.c_str(), other.mount_point.c_str());
}
}
}
if (conf_debug_pruning) {
- /* This is debugging output, don't mark anything for translation */
fprintf(stderr, "...done\n");
}
string_list_dir_path_sort(&bind_mount_paths);
}
/* Initialize state for is_bind_mount(), to read data from MOUNTINFO. */
-void bind_mount_init(const char *mountinfo)
+void bind_mount_init()
{
- mountinfo_path = mountinfo;
- mountinfo_fd = open(mountinfo_path, O_RDONLY);
+ mountinfo_fd = open(MOUNTINFO_PATH, O_RDONLY);
if (mountinfo_fd == -1)
return;
rebuild_bind_mount_paths();