From 207df6fc406e81bfeebdff7f404bd242ff3f099f Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Tue, 7 May 2024 06:48:35 +0200 Subject: Merging upstream version 0.12.2. Signed-off-by: Daniel Baumann --- src/base/fs_util.cc | 62 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 4 deletions(-) (limited to 'src/base/fs_util.cc') diff --git a/src/base/fs_util.cc b/src/base/fs_util.cc index f72aaa6..7cbc228 100644 --- a/src/base/fs_util.cc +++ b/src/base/fs_util.cc @@ -29,14 +29,30 @@ #include "fs_util.hh" +#include + #include "config.h" #include "fmt/format.h" #include "itertools.hh" +#include "lnav_log.hh" #include "opt_util.hh" namespace lnav { namespace filesystem { +Result +realpath(const ghc::filesystem::path& path) +{ + char resolved[PATH_MAX]; + auto rc = ::realpath(path.c_str(), resolved); + + if (rc == nullptr) { + return Err(std::string(strerror(errno))); + } + + return Ok(ghc::filesystem::path(resolved)); +} + Result create_file(const ghc::filesystem::path& path, int flags, mode_t mode) { @@ -73,7 +89,7 @@ open_temp_file(const ghc::filesystem::path& pattern) int fd; strcpy(pattern_copy, pattern_str.c_str()); - if ((fd = mkstemp(pattern_copy)) == -1) { + if ((fd = mkostemp(pattern_copy, O_CLOEXEC)) == -1) { return Err( fmt::format(FMT_STRING("unable to create temporary file: {} -- {}"), pattern.string(), @@ -102,9 +118,12 @@ read_file(const ghc::filesystem::path& path) } } -Result -write_file(const ghc::filesystem::path& path, const string_fragment& content) +Result +write_file(const ghc::filesystem::path& path, + const string_fragment& content, + std::set options) { + write_file_result retval; auto tmp_pattern = path; tmp_pattern += ".XXXXXX"; @@ -123,7 +142,25 @@ write_file(const ghc::filesystem::path& path, const string_fragment& content) bytes_written, content.length())); } + std::error_code ec; + if (options.count(write_file_options::backup_existing)) { + if (ghc::filesystem::exists(path, ec)) { + auto backup_path = path; + + backup_path += ".bak"; + ghc::filesystem::rename(path, backup_path, ec); + if (ec) { + return Err( + fmt::format(FMT_STRING("unable to backup file {}: {}"), + path.string(), + ec.message())); + } + + retval.wfr_backup_path = backup_path; + } + } + ghc::filesystem::rename(tmp_pair.first, path, ec); if (ec) { return Err( @@ -132,7 +169,7 @@ write_file(const ghc::filesystem::path& path, const string_fragment& content) ec.message())); } - return Ok(); + return Ok(retval); } std::string @@ -181,3 +218,20 @@ file_lock::file_lock(const ghc::filesystem::path& archive_path) } // namespace filesystem } // namespace lnav + +namespace fmt { + +auto +formatter::format(const ghc::filesystem::path& p, + format_context& ctx) + -> decltype(ctx.out()) const +{ + auto esc_res = fmt::v10::detail::find_escape(&(*p.native().begin()), + &(*p.native().end())); + if (esc_res.end == nullptr) { + return formatter::format(p.native(), ctx); + } + + return format_to(ctx.out(), FMT_STRING("{:?}"), p.native()); +} +} // namespace fmt -- cgit v1.2.3