SB++
Sandbox applications
Loading...
Searching...
No Matches
shared.hpp
1#pragma once
5
6
7#include <filesystem>
8#include <set>
9#include <sys/inotify.h>
10#include <random>
11#include <fcntl.h>
12#include <csignal>
13#include <exec.hpp>
14
15#ifdef PROFILE
16#include <map>
17#endif
18
19#include "third_party/thread-pool/include/BS_thread_pool.hpp"
20
21namespace shared {
22
23 // The thread pool
24 extern BS::thread_pool<BS::tp::wait_deadlock_checks> pool;
25
26 // Environment variables
27 extern const std::string runtime, config, cache, data, home, session, nobody, real;
28
29 extern std::filesystem::path data_dir, app_data;
30
31 // Our inotify watch
32 extern int inotify;
33
34 // Definitions.
35 using set = std::set<std::string>;
36 using vector = std::vector<std::string>;
37 using list = std::initializer_list<std::string_view>;
38
39
45 private:
46 static std::random_device dev;
47 static std::mt19937 prng;
48 static std::uniform_int_distribution<uint64_t> rand;
49
50 // The path, and the name
51 std::string path;
52 std::string name;
53
60 void generate(const std::string_view& parent, const std::string_view& prefix, const std::string_view& suffix) {
61 path.reserve(parent.length() + prefix.length() + suffix.length() + 17);
62 path.append(parent); if (!parent.ends_with('/')) path += '/';
63
64 std::stringstream name_stream;
65 if (!prefix.empty()) name_stream << prefix << '-';
66 name_stream << std::hex << rand(prng);
67 if (!suffix.empty()) name_stream << '-' << suffix;
68 name = name_stream.str();
69 path += name;
70 }
71
72 public:
73
83 const std::string& parent = std::filesystem::temp_directory_path(),
84 const std::string_view& prefix = "", const std::string_view& suffix = "",
85 const bool& defer = false
86 ) {
87 do {
88 generate(parent, prefix, suffix);
89 } while (std::filesystem::is_directory(path));
90 if (!defer) create();
91 }
92
93 // Obliterate the directory.
94 ~TemporaryDirectory() {std::filesystem::remove_all(path);}
95
100 const std::string& get_path() const {return path;}
101
105 void create() const {std::filesystem::create_directories(path);}
106
114 std::string sub(const std::string& name, const bool& dir = false) const {
115 const auto new_path = path + "/" + name;
116 if (dir) std::filesystem::create_directories(new_path);
117 return new_path;
118 }
119
123 const std::string& get_name() const {return name;}
124 };
125
130 void log(const list& msg, const std::string& level="log");
131
132
139 template <class T = list> void extend(vector& dest, T source);
140 template <class T = list> void extend(set& dest, T source);
141 void extend(set& dest, set source);
142
143
151 template <class T = vector> std::string join(const T& list, const char& joiner = ' ');
152
153
160 template <typename T = char> std::string strip(const std::string_view& in, const T& to_strip);
161
162
172 template <typename T = char> std::string trim(const std::string& in, const T& to_strip);
173
174
182 set wildcard(const std::string_view& pattern, const std::string_view& path, const list& args = {});
183
184
190 std::string escape(const std::string& in);
191
192
199 void share(vector& command, const std::string_view& path, const std::string& mode = "ro-bind");
200
201
208 void merge(set& command, set path);
209
210
217 void genv(vector& command, const std::string_view& env);
218
219
225 void inotify_wait(const int& wd, const std::string_view& name = "");
226
227
233 std::string hash(const std::string_view& in);
234
247 template <class T, class A, class L = list, class ...Args> void single_batch(const A& fun, T& accum, const L& mem, Args&&... args) {
248 for (const auto& val : mem) fun(accum, val, args...);
249 }
250
264 template <class T, class A, class L = list, class ...Args> void batch(const A& fun, T& accum, const L& mem, Args&&... args) {
265 std::vector<std::future<T>> futures; futures.reserve(mem.size());
266 for (auto& val : mem) {
267 futures.emplace_back(pool.submit_task([val = std::move(val), &fun, &args...]() {return container::init<T>(fun, val, args...);}));
268 }
269 for (auto& future : futures) extend(accum, future.get());
270 }
271
272
279 void extend(vector& dest, const std::initializer_list<const list>& source);
280
281
282 // Profiling stuff :)
283 #ifdef PROFILE
284 extern std::map<std::string, uint_fast32_t> time_slice;
285
286 template <typename T> inline void profile(const std::string& name, T func) {
287 auto begin = std::chrono::high_resolution_clock::now();
288 func();
289 auto duration = duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - begin).count();
290 time_slice["total"] += duration;
291 time_slice[name] = duration;
292 log({name, ":", std::to_string(duration), "us"});
293 }
294 #else
295 #define profile(name, func) func();
296 #endif
297}
A Temporary Directory A directory that destroys itself upon falling out of scope.
Definition shared.hpp:44
TemporaryDirectory(const std::string &parent=std::filesystem::temp_directory_path(), const std::string_view &prefix="", const std::string_view &suffix="", const bool &defer=false)
Construct a Temporary Directory.
Definition shared.hpp:82
const std::string & get_name() const
Return the name of the directory, excluding the path.
Definition shared.hpp:123
void create() const
Create the directory.
Definition shared.hpp:105
const std::string & get_path() const
Return the path to the directory.
Definition shared.hpp:100
std::string sub(const std::string &name, const bool &dir=false) const
Create a subdirectory/file in the temp dir.
Definition shared.hpp:114
Generator functions. This header contains generator functions, either used to assemble the bwrap comm...
Definition generators.cpp:15
Shared functionality.
Definition shared.cpp:11
void genv(vector &command, const std::string_view &env)
Attach an environment variable to the sandbox.
Definition shared.cpp:106
void extend(vector &dest, T source)
Extend a container in place.
Definition shared.cpp:114
std::string join(const T &list, const char &joiner)
Join a vector into a string.
Definition shared.cpp:54
std::string hash(const std::string_view &in)
Hash a string.
Definition shared.cpp:159
std::string escape(const std::string &in)
Escape a string.
set wildcard(const std::string_view &pattern, const std::string_view &path, const list &args)
Resolve wildcard patterns.
Definition shared.cpp:92
std::string trim(const std::string &in, const T &to_strip)
Trim characters from the front and end of a string.
Definition shared.cpp:80
void single_batch(const A &fun, T &accum, const L &mem, Args &&... args)
Batch multiple iterations of an accumulator function together.
Definition shared.hpp:247
void batch(const A &fun, T &accum, const L &mem, Args &&... args)
Batch multiple iterations of an accumulator function together, threaded.
Definition shared.hpp:264
void log(const list &msg, const std::string &level)
Log output to console, if verbose.
Definition shared.cpp:40
void merge(set &command, set path)
Merge two sets together.
void share(vector &command, const std::string_view &path, const std::string &mode)
Share a path with the sandbox using a mode.
Definition shared.cpp:148
void inotify_wait(const int &wd, const std::string_view &name)
Wait for an inotify watcher.
Definition shared.cpp:134
std::string strip(const std::string_view &in, const T &to_strip)
Strip all instance of character from a string.
Definition shared.cpp:68