From: Joel Rosdahl Date: Sat, 15 Jul 2023 14:06:31 +0000 (+0200) Subject: refactor: Create util::filesystem wrappers returning nonstd::expected X-Git-Tag: v4.9~122 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=709701ac1802721605f8c5a90a42eaf6505da7f8;p=thirdparty%2Fccache.git refactor: Create util::filesystem wrappers returning nonstd::expected --- diff --git a/src/MiniTrace.cpp b/src/MiniTrace.cpp index f52564649..db4141d03 100644 --- a/src/MiniTrace.cpp +++ b/src/MiniTrace.cpp @@ -26,25 +26,23 @@ #include #include #include +#include #ifdef HAVE_UNISTD_H # include #endif -#include - -namespace fs = std::filesystem; +namespace fs = util::filesystem; MiniTrace::MiniTrace(const ArgsInfo& args_info) : m_args_info(args_info), m_trace_id(reinterpret_cast(getpid())) { - std::error_code ec; - auto tmp_dir = fs::temp_directory_path(ec); - if (ec) { + auto tmp_dir = fs::temp_directory_path(); + if (!tmp_dir) { tmp_dir = "/tmp"; } - TemporaryFile tmp_file((tmp_dir / "ccache-trace").string()); + TemporaryFile tmp_file((*tmp_dir / "ccache-trace").string()); m_tmp_trace_file = tmp_file.path; mtr_init(m_tmp_trace_file.c_str()); diff --git a/src/Util.cpp b/src/Util.cpp index 9b157b6db..afd28d4e0 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -51,7 +52,7 @@ using IncludeDelimiter = util::Tokenizer::IncludeDelimiter; -namespace fs = std::filesystem; +namespace fs = util::filesystem; namespace { @@ -284,12 +285,15 @@ ensure_dir_exists(std::string_view dir) std::string get_actual_cwd() { - std::error_code ec; - auto cwd = fs::current_path(ec).string(); + auto cwd = fs::current_path(); + if (!cwd) { + return {}; + } + auto cwd_str = cwd->string(); #ifdef _WIN32 - std::replace(cwd.begin(), cwd.end(), '\\', '/'); + std::replace(cwd_str.begin(), cwd_str.end(), '\\', '/'); #endif - return cwd; + return cwd_str; } std::string diff --git a/src/ccache.cpp b/src/ccache.cpp index 75dc41b60..45b7b1af4 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -65,7 +66,6 @@ #include -#include #include #include @@ -80,7 +80,7 @@ #include #include -namespace fs = std::filesystem; +namespace fs = util::filesystem; using core::Statistic; @@ -245,17 +245,16 @@ guess_compiler(std::string_view path) // Follow symlinks to the real compiler to learn its name. We're not using // util::real_path in order to save some unnecessary stat calls. while (true) { - std::error_code ec; - auto symlink_target = fs::read_symlink(compiler_path, ec); - if (ec) { + auto symlink_target = fs::read_symlink(compiler_path); + if (!symlink_target) { // Not a symlink. break; } - if (symlink_target.is_absolute()) { - compiler_path = symlink_target; + if (symlink_target->is_absolute()) { + compiler_path = *symlink_target; } else { compiler_path = - FMT("{}/{}", Util::dir_name(compiler_path), symlink_target.string()); + FMT("{}/{}", Util::dir_name(compiler_path), symlink_target->string()); } } #endif diff --git a/src/storage/local/LocalStorage.cpp b/src/storage/local/LocalStorage.cpp index 5410bc962..9aaf2c6be 100644 --- a/src/storage/local/LocalStorage.cpp +++ b/src/storage/local/LocalStorage.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -78,13 +79,12 @@ #include #include #include -#include #include #include #include #include -namespace fs = std::filesystem; +namespace fs = util::filesystem; using core::Statistic; using core::StatisticsCounters; @@ -650,11 +650,16 @@ LocalStorage::clone_hard_link_or_copy_file(const std::string& source, // run, but it's only we who can create the file entry now so we don't try // to handle a race between remove() and create_hard_link() below. - std::error_code ec; - fs::remove(dest, ec); // Ignore any error. + fs::remove(dest); // Ignore any error. LOG("Hard linking {} to {}", source, dest); - fs::create_hard_link(source, dest, ec); - if (!ec) { + if (auto result = fs::create_hard_link(source, dest); !result) { + LOG("Failed to hard link {} to {}: {}", + source, + dest, + result.error().message()); + // Fall back to copying. + } else { + // Success. #ifndef _WIN32 if (chmod(dest.c_str(), 0444 & ~util::get_umask()) != 0) { LOG("Failed to chmod {}: {}", dest.c_str(), strerror(errno)); @@ -662,8 +667,6 @@ LocalStorage::clone_hard_link_or_copy_file(const std::string& source, #endif return; } - LOG("Failed to hard link {} to {}: {}", source, dest, ec.message()); - // Fall back to copying. } LOG("Copying {} to {}", source, dest); diff --git a/src/util/LockFile.cpp b/src/util/LockFile.cpp index 033469868..219a63535 100644 --- a/src/util/LockFile.cpp +++ b/src/util/LockFile.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "third_party/fmt/core.h" @@ -44,7 +45,7 @@ const double k_max_sleep_time = 0.050; const util::Duration k_staleness_limit(2); #endif -namespace fs = std::filesystem; +namespace fs = util::filesystem; namespace { @@ -262,18 +263,20 @@ LockFile::do_acquire(const bool blocking) return false; } - std::error_code ec; - std::string content = fs::read_symlink(m_lock_file, ec); - if (ec) { - if (ec == std::errc::no_such_file_or_directory) { + auto content_path = fs::read_symlink(m_lock_file); + if (!content_path) { + if (content_path.error() == std::errc::no_such_file_or_directory) { // The symlink was removed after the symlink() call above, so retry // acquiring it. continue; } else { - LOG("Could not read symlink {}: {}", m_lock_file, ec.message()); + LOG("Could not read symlink {}: {}", + m_lock_file, + content_path.error().message()); return false; } } + auto content = content_path->string(); if (content == my_content) { // Lost NFS reply? diff --git a/src/util/filesystem.hpp b/src/util/filesystem.hpp new file mode 100644 index 000000000..f780164b9 --- /dev/null +++ b/src/util/filesystem.hpp @@ -0,0 +1,73 @@ +// Copyright (C) 2023 Joel Rosdahl and other contributors +// +// See doc/AUTHORS.adoc for a complete list of contributors. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Software Foundation, Inc., 51 +// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#pragma once + +#include + +#include + +namespace util::filesystem { + +using directory_iterator = std::filesystem::directory_iterator; +using path = std::filesystem::path; + +#define DEFINE_FS_WRAPPER(name_, fnspec_) \ + template \ + nonstd::expected \ + name_(Args&&... args) \ + { \ + std::error_code ec; \ + if constexpr (std::is_same::value) { \ + std::filesystem::name_(std::forward(args)..., ec); \ + if (ec) { \ + return nonstd::make_unexpected(ec); \ + } \ + return {}; \ + } else { \ + auto result = std::filesystem::name_(std::forward(args)..., ec); \ + if (ec) { \ + return nonstd::make_unexpected(ec); \ + } \ + return result; \ + } \ + } + +#define DEFINE_FS_PREDICATE_WRAPPER(name_, fnspec_) \ + template bool name_(Args&&... args) \ + { \ + std::error_code ec; \ + auto result = std::filesystem::name_(std::forward(args)..., ec); \ + return !ec && result; \ + } + +DEFINE_FS_WRAPPER(canonical, (path{})) +DEFINE_FS_WRAPPER(create_hard_link, (path{}, path{})) +DEFINE_FS_WRAPPER(current_path, ()) +DEFINE_FS_WRAPPER(read_symlink, (path{})) +DEFINE_FS_WRAPPER(remove, (path{})) +DEFINE_FS_WRAPPER(temp_directory_path, ()) + +DEFINE_FS_PREDICATE_WRAPPER(exists, (path{})) +DEFINE_FS_PREDICATE_WRAPPER(is_directory, (path{})) + +#undef DEFINE_FS_PREDICATE_WRAPPER +#undef DEFINE_FS_WRAPPER + +} // namespace util::filesystem diff --git a/src/util/path.cpp b/src/util/path.cpp index 5a9ab4add..1106a6d65 100644 --- a/src/util/path.cpp +++ b/src/util/path.cpp @@ -20,6 +20,7 @@ #include #include +#include #ifdef _WIN32 const char k_dev_null_path[] = "nul:"; @@ -29,7 +30,7 @@ const char k_dev_null_path[] = "/dev/null"; const char k_path_delimiter[] = ":"; #endif -namespace fs = std::filesystem; +namespace fs = util::filesystem; namespace util { @@ -90,9 +91,8 @@ path_starts_with(std::string_view path, std::string_view prefix) std::string real_path(std::string_view path) { - std::error_code ec; - auto real_path = fs::canonical(path, ec).string(); - return ec ? std::string(path) : real_path; + auto real_path = fs::canonical(path); + return real_path ? real_path->string() : std::string(path); } std::vector