diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-07 04:48:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-07 04:48:35 +0000 |
commit | 207df6fc406e81bfeebdff7f404bd242ff3f099f (patch) | |
tree | a1a796b056909dd0a04ffec163db9363a8757808 /src/base/fs_util.cc | |
parent | Releasing progress-linux version 0.11.2-1~progress7.99u1. (diff) | |
download | lnav-207df6fc406e81bfeebdff7f404bd242ff3f099f.tar.xz lnav-207df6fc406e81bfeebdff7f404bd242ff3f099f.zip |
Merging upstream version 0.12.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/base/fs_util.cc')
-rw-r--r-- | src/base/fs_util.cc | 62 |
1 files changed, 58 insertions, 4 deletions
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 <stdlib.h> + #include "config.h" #include "fmt/format.h" #include "itertools.hh" +#include "lnav_log.hh" #include "opt_util.hh" namespace lnav { namespace filesystem { +Result<ghc::filesystem::path, std::string> +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<auto_fd, std::string> 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<void, std::string> -write_file(const ghc::filesystem::path& path, const string_fragment& content) +Result<write_file_result, std::string> +write_file(const ghc::filesystem::path& path, + const string_fragment& content, + std::set<write_file_options> 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<ghc::filesystem::path>::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<string_view>::format(p.native(), ctx); + } + + return format_to(ctx.out(), FMT_STRING("{:?}"), p.native()); +} +} // namespace fmt |