From: Joel Rosdahl Date: Sun, 9 Jul 2023 17:08:20 +0000 (+0200) Subject: refactor: Move copy_file to util X-Git-Tag: v4.9~140 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=73a4585a58d5ab818a864485708d706532dfa3b4;p=thirdparty%2Fccache.git refactor: Move copy_file to util --- diff --git a/src/MiniTrace.cpp b/src/MiniTrace.cpp index cd9f4f809..cbda28ad4 100644 --- a/src/MiniTrace.cpp +++ b/src/MiniTrace.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2022 Joel Rosdahl and other contributors +// Copyright (C) 2020-2023 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -25,6 +25,7 @@ #include #include +#include #include // NOLINT: PATH_MAX is defined in limits.h @@ -76,7 +77,7 @@ MiniTrace::~MiniTrace() mtr_shutdown(); if (!m_args_info.output_obj.empty()) { - Util::copy_file(m_tmp_trace_file, m_args_info.output_obj + ".ccache-trace"); + util::copy_file(m_tmp_trace_file, m_args_info.output_obj + ".ccache-trace"); } Util::unlink_tmp(m_tmp_trace_file); } diff --git a/src/Util.cpp b/src/Util.cpp index 8c253de23..ee0890fdc 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -223,49 +223,6 @@ common_dir_prefix_length(std::string_view dir, std::string_view path) return i; } -void -copy_fd(int fd_in, int fd_out) -{ - util::read_fd(fd_in, [=](nonstd::span data) { - util::write_fd(fd_out, data.data(), data.size()); - }); -} - -void -copy_file(const std::string& src, const std::string& dest, bool via_tmp_file) -{ - Fd src_fd(open(src.c_str(), O_RDONLY | O_BINARY)); - if (!src_fd) { - throw core::Error( - FMT("Failed to open {} for reading: {}", src, strerror(errno))); - } - - unlink(dest.c_str()); - - Fd dest_fd; - std::string tmp_file; - if (via_tmp_file) { - TemporaryFile temp_file(dest); - dest_fd = std::move(temp_file.fd); - tmp_file = temp_file.path; - } else { - dest_fd = - Fd(open(dest.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)); - if (!dest_fd) { - throw core::Error( - FMT("Failed to open {} for writing: {}", dest, strerror(errno))); - } - } - - copy_fd(*src_fd, *dest_fd); - dest_fd.close(); - src_fd.close(); - - if (via_tmp_file) { - Util::rename(tmp_file, dest); - } -} - bool create_dir(std::string_view dir) { diff --git a/src/Util.hpp b/src/Util.hpp index d157808d1..bafd185a8 100644 --- a/src/Util.hpp +++ b/src/Util.hpp @@ -53,15 +53,6 @@ std::string change_extension(std::string_view path, std::string_view new_ext); // `dir` (a directory) and `path` (any path). size_t common_dir_prefix_length(std::string_view dir, std::string_view path); -// Copy all data from `fd_in` to `fd_out`. Throws `core::Error` on error. -void copy_fd(int fd_in, int fd_out); - -// Copy a file from `src` to `dest`. If via_tmp_file is true, `src` is copied to -// a temporary file and then renamed to dest. Throws `core::Error` on error. -void copy_file(const std::string& src, - const std::string& dest, - bool via_tmp_file = false); - // Create a directory if needed, including its parents if needed. // // Returns true if the directory exists or could be created, otherwise false. diff --git a/src/storage/local/LocalStorage.cpp b/src/storage/local/LocalStorage.cpp index ebc13ed43..bfb20ae3a 100644 --- a/src/storage/local/LocalStorage.cpp +++ b/src/storage/local/LocalStorage.cpp @@ -654,7 +654,8 @@ LocalStorage::clone_hard_link_or_copy_file(const std::string& source, } LOG("Copying {} to {}", source, dest); - Util::copy_file(source, dest, via_tmp_file); + util::copy_file( + source, dest, via_tmp_file ? util::ViaTmpFile::yes : util::ViaTmpFile::no); } void diff --git a/src/util/file.cpp b/src/util/file.cpp index 7b80b584b..48d987af6 100644 --- a/src/util/file.cpp +++ b/src/util/file.cpp @@ -21,9 +21,12 @@ #include #include #include +#include +#include #include #include #include +#include #ifdef HAVE_UNISTD_H # include @@ -56,6 +59,47 @@ namespace util { +nonstd::expected +copy_file(const std::string& src, + const std::string& dest, + ViaTmpFile via_tmp_file) +{ + Fd src_fd(open(src.c_str(), O_RDONLY | O_BINARY)); + if (!src_fd) { + return nonstd::make_unexpected( + FMT("Failed to open {} for reading: {}", src, strerror(errno))); + } + + unlink(dest.c_str()); + + Fd dest_fd; + std::string tmp_file; + if (via_tmp_file == ViaTmpFile::yes) { + TemporaryFile temp_file(dest); + dest_fd = std::move(temp_file.fd); + tmp_file = temp_file.path; + } else { + dest_fd = + Fd(open(dest.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)); + if (!dest_fd) { + return nonstd::make_unexpected( + FMT("Failed to open {} for writing: {}", dest, strerror(errno))); + } + } + TRY(util::read_fd(*src_fd, [&](nonstd::span data) { + util::write_fd(*dest_fd, data.data(), data.size()); + })); + + dest_fd.close(); + src_fd.close(); + + if (via_tmp_file == ViaTmpFile::yes) { + Util::rename(tmp_file, dest); + } + + return {}; +} + void create_cachedir_tag(const std::string& dir) { diff --git a/src/util/file.hpp b/src/util/file.hpp index 0ae0a57f2..286974e00 100644 --- a/src/util/file.hpp +++ b/src/util/file.hpp @@ -36,6 +36,14 @@ namespace util { // --- Interface --- enum class InPlace { yes, no }; +enum class ViaTmpFile { yes, no }; + +// Copy a file from `src` to `dest`. If `via_tmp_file` is yes, `src` is copied +// to a temporary file and then renamed to dest. +nonstd::expected +copy_file(const std::string& src, + const std::string& dest, + ViaTmpFile via_tmp_file = ViaTmpFile::no); void create_cachedir_tag(const std::string& dir);