FlatImage
A configurable Linux containerization system
Loading...
Searching...
No Matches
unshare.hpp
Go to the documentation of this file.
1
8
9#pragma once
10
11#include <map>
12#include <cstring>
13#include <set>
14#include <ranges>
15
16#include "reserved.hpp"
17#include "../std/enum.hpp"
18#include "../std/expected.hpp"
19
32{
33
34namespace
35{
36
37namespace fs = std::filesystem;
38
39}
40
41// Unshare bits (stored as uint16_t, 2 bytes)
42using Bits = uint16_t;
43
44// Unshare options as fields
45ENUM(Unshare,ALL,USER,IPC,PID,NET,UTS,CGROUP);
46
47// Corresponding bit position index
48inline std::map<Unshare,Bits> const unshare_mask =
49{
50 {Unshare::USER, Bits{1} << 0},
51 {Unshare::IPC, Bits{1} << 1},
52 {Unshare::PID, Bits{1} << 2},
53 {Unshare::NET, Bits{1} << 3},
54 {Unshare::UTS, Bits{1} << 4},
55 {Unshare::CGROUP, Bits{1} << 5},
56};
57
66[[nodiscard]] inline Value<void> bit_set(Bits& bits, Unshare const& unshare, bool value) noexcept
67{
68 auto it = unshare_mask.find(unshare);
69 return_if(it == unshare_mask.end(), Error("E::Unshare option '{}' not found", unshare));
70 Bits mask = it->second;
71 if (value) { bits |= mask; }
72 else { bits &= ~mask; }
73 return {};
74}
75
82[[nodiscard]] inline std::set<std::string> to_strings(Bits const& bits) noexcept
83{
84 std::set<std::string> out;
85 for(auto&& [unshare,mask] : unshare_mask)
86 {
87 if(bits & mask)
88 {
89 std::string str = unshare;
90 std::ranges::transform(str, str.begin(), ::tolower);
91 out.insert(str);
92 }
93 }
94 return out;
95}
96
104inline Value<void> write(fs::path const& path_file_binary, Bits const& bits) noexcept
105{
106 static_assert(sizeof(Bits) == sizeof(uint16_t), "Bits size must be 2 bytes");
107 uint64_t offset_begin = ns_reserved::FIM_RESERVED_OFFSET_UNSHARE_BEGIN;
108 uint64_t offset_end = ns_reserved::FIM_RESERVED_OFFSET_UNSHARE_END;
109 return ns_reserved::write(path_file_binary, offset_begin, offset_end, reinterpret_cast<char const*>(&bits), sizeof(bits));
110}
111
118inline Value<Bits> read(fs::path const& path_file_binary) noexcept
119{
120 static_assert(sizeof(Bits) == sizeof(uint16_t), "Bits size must be 2 bytes");
121 uint64_t offset_begin = ns_reserved::FIM_RESERVED_OFFSET_UNSHARE_BEGIN;
122 uint64_t size = ns_reserved::FIM_RESERVED_OFFSET_UNSHARE_END - offset_begin;
123 constexpr size_t const size_bits = sizeof(Bits);
124 return_if(size_bits != size, Error("E::Trying to read an exceeding number of bytes: {} vs {}", size_bits, size));
125 Bits bits;
126 Pop(ns_reserved::read(path_file_binary, offset_begin, reinterpret_cast<char*>(&bits), size_bits));
127 return bits;
128}
129
134{
135 private:
136 fs::path m_path_file_binary;
137
138 Value<void> set_unshares(Bits bits, std::set<Unshare> const& unshares, bool value)
139 {
140 if(unshares.contains(Unshare::NONE))
141 {
142 return Error("E::Invalid unshare option 'NONE'");
143 }
144 if(unshares.contains(Unshare::ALL))
145 {
146 return_if(unshares.size() > 1, Error("E::Unshare option 'all' should not be used with others"));
147 return this->set_all(true);
148 }
149 for(Unshare const& unshare : unshares)
150 {
151 Pop(bit_set(bits, unshare, value));
152 };
153 Pop(write(m_path_file_binary, bits));
154 return {};
155 }
156 public:
161 Unshares(fs::path const& path_file_binary)
162 : m_path_file_binary(path_file_binary)
163 {}
164
170 [[nodiscard]] inline Value<void> set_all(bool value)
171 {
172 auto unshares = unshare_mask
173 | std::views::transform([](auto&& e){ return e.first; })
174 | std::views::filter([](auto&& e){ return e != Unshare::ALL; })
175 | std::ranges::to<std::set<Unshare>>();
176 return set_unshares(Bits{}, unshares, value);
177 }
178
184 [[nodiscard]] inline Value<void> set(std::set<Unshare> const& unshares)
185 {
186 return set_unshares(Bits{}, unshares, true);
187 }
188
194 [[nodiscard]] inline Value<void> add(std::set<Unshare> const& unshares)
195 {
196 return set_unshares(Pop(read(m_path_file_binary)), unshares, true);
197 }
198
204 [[nodiscard]] inline Value<void> del(std::set<Unshare> const& unshares)
205 {
206 return set_unshares(Pop(read(m_path_file_binary)), unshares, false);
207 }
208
214 [[nodiscard]] inline bool contains(Unshare const& unshare) const noexcept
215 {
216 return_if(unshare == Unshare::NONE or unshare == Unshare::ALL, false);
217 Bits bits = read(m_path_file_binary).value_or(0);
218 auto it = unshare_mask.find(unshare);
219 return_if(it == unshare_mask.end(), false);
220 return (bits & it->second) != 0;
221 }
222
227 [[nodiscard]] inline Value<void> clear() noexcept
228 {
229 return write(m_path_file_binary, Bits{});
230 }
231
236 [[nodiscard]] inline Value<std::set<std::string>> to_strings() const noexcept
237 {
238 return ::ns_reserved::ns_unshare::to_strings(Pop(read(m_path_file_binary)));
239 }
240};
241
242} // namespace ns_reserved::ns_unshare
243
244/* vim: set expandtab fdm=marker ts=2 sw=2 tw=100 et :*/
Unshares(fs::path const &path_file_binary)
Constructs an Unshares manager for the given binary.
Definition unshare.hpp:161
Value< void > set(std::set< Unshare > const &unshares)
Sets the specified unshare options (replaces existing)
Definition unshare.hpp:184
Value< void > del(std::set< Unshare > const &unshares)
Removes unshare options from existing configuration.
Definition unshare.hpp:204
bool contains(Unshare const &unshare) const noexcept
Checks if a specific unshare option is enabled.
Definition unshare.hpp:214
Value< void > clear() noexcept
Clears all unshare options.
Definition unshare.hpp:227
Value< std::set< std::string > > to_strings() const noexcept
Converts enabled unshare options to string representations.
Definition unshare.hpp:236
Value< void > add(std::set< Unshare > const &unshares)
Adds unshare options to existing configuration.
Definition unshare.hpp:194
Value< void > set_all(bool value)
Sets all unshare options to the specified value.
Definition unshare.hpp:170
Custom enumeration class.
Enhanced error handling framework built on std::expected.
Unshare namespace options bitfield management in reserved space.
std::set< std::string > to_strings(Bits const &bits) noexcept
Creates a set of lowercase string unshare option representations.
Definition unshare.hpp:82
Value< void > bit_set(Bits &bits, Unshare const &unshare, bool value) noexcept
Sets a bit unshare option with the target value.
Definition unshare.hpp:66
Value< Bits > read(fs::path const &path_file_binary) noexcept
Read the Bits struct from the given binary.
Definition unshare.hpp:118
Value< void > write(fs::path const &path_file_binary, Bits const &bits) noexcept
Write the Bits struct to the given binary.
Definition unshare.hpp:104
Value< void > write(fs::path const &path_file_binary, uint64_t offset_begin, uint64_t offset_end, const char *data, uint64_t length) noexcept
Writes data to a file in binary format.
Definition reserved.hpp:142
Value< std::streamsize > read(fs::path const &path_file_binary, uint64_t offset, char *data, uint64_t length) noexcept
Reads data from a file in binary format.
Definition reserved.hpp:172
Manages reserved space.
Enhanced expected type with integrated logging capabilities.
Definition expected.hpp:44