aboutsummaryrefslogtreecommitdiffstats
path: root/liblfjail/fileutils.hh
diff options
context:
space:
mode:
authorLexi Winter <ivy@FreeBSD.org>2025-06-16 16:52:11 +0100
committerLexi Winter <ivy@FreeBSD.org>2025-06-16 16:52:11 +0100
commit253c4648431d4333b29baaffb3419882bfbb31ff (patch)
tree8973e230e6e2627dfded464e1dcade209136d814 /liblfjail/fileutils.hh
parent8129d0ef4629f44cd89e3b79e8b66129bb9dc866 (diff)
downloadlfjail-253c4648431d4333b29baaffb3419882bfbb31ff.tar.gz
lfjail-253c4648431d4333b29baaffb3419882bfbb31ff.tar.bz2
updatesmain
Diffstat (limited to 'liblfjail/fileutils.hh')
-rw-r--r--liblfjail/fileutils.hh40
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);