diff options
| author | Lexi Winter <ivy@FreeBSD.org> | 2025-06-16 16:52:11 +0100 |
|---|---|---|
| committer | Lexi Winter <ivy@FreeBSD.org> | 2025-06-16 16:52:11 +0100 |
| commit | 253c4648431d4333b29baaffb3419882bfbb31ff (patch) | |
| tree | 8973e230e6e2627dfded464e1dcade209136d814 /liblfjail/fileutils.hh | |
| parent | 8129d0ef4629f44cd89e3b79e8b66129bb9dc866 (diff) | |
| download | lfjail-253c4648431d4333b29baaffb3419882bfbb31ff.tar.gz lfjail-253c4648431d4333b29baaffb3419882bfbb31ff.tar.bz2 | |
updatesmain
Diffstat (limited to 'liblfjail/fileutils.hh')
| -rw-r--r-- | liblfjail/fileutils.hh | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/liblfjail/fileutils.hh b/liblfjail/fileutils.hh index 0824796..0f7c1a7 100644 --- a/liblfjail/fileutils.hh +++ b/liblfjail/fileutils.hh @@ -7,6 +7,8 @@ #include <array> #include <iterator> +#include <filesystem> +#include <format> #include <ranges> #include <span> #include <string> @@ -19,16 +21,37 @@ #include "io_error.hh" #include "guard.hh" +/* + * std::formatter for path was only added in C++26; LLVM 19 doesn't have it. + */ + +#ifndef __cpp_lib_format_path +template<> +struct std::formatter<std::filesystem::path, char> +{ + template<typename ParseContext> + constexpr auto parse(ParseContext &ctx) -> ParseContext::iterator { + return ctx.begin(); + } + + template<typename FmtContext> + auto format(std::filesystem::path const &path, + FmtContext& ctx) const -> FmtContext::iterator { + return std::ranges::copy(path.native(), ctx.out()).out; + } +}; +#endif // !__cpp_lib_format_path + namespace lfjail { -void ensure_dir(context const &ctx, std::string_view dir); +void ensure_dir(context const &ctx, std::filesystem::path const &dir); /* * Load the contents of a file into an output iterator. Throws io_error * on failure. */ -void read_file(std::string filename, +void read_file(std::filesystem::path const &filename, std::output_iterator<char> auto &&iter) { constexpr std::size_t bufsize = 1024; @@ -54,7 +77,8 @@ void read_file(std::string filename, * Write the contents of a range to a file. Throws io_error on error. */ -void write_file(std::string filename, std::ranges::range auto &&range) { +void write_file(std::filesystem::path const &filename, + std::ranges::range auto &&range) { // Convert the range into an array. std::vector<char> chars; std::ranges::copy(range, std::back_inserter(chars)); @@ -78,11 +102,15 @@ void write_file(std::string filename, std::ranges::range auto &&range) { * renamed to the target filename. If an error occurs, the target file will * not be modified. */ -void safe_write_file(std::string filename, std::ranges::range auto &&range) { - auto tmpfile = filename + ".tmp"; +void safe_write_file(std::filesystem::path const &filename, + std::ranges::range auto &&range) { + auto tmpfile(filename); + tmpfile.remove_filename(); + tmpfile /= (filename.filename().native() + ".tmp"); + auto tmpfile_guard = guard([tmpfile] { ::unlink(tmpfile.c_str()); }); - write_file(tmpfile, range); + write_file(tmpfile, std::forward<decltype(range)>(range)); int err = ::rename(tmpfile.c_str(), filename.c_str()); if (err != 0) throw io_error(filename, errno); |
