#include <core/wincompat.hpp>
#include <util/TimePoint.hpp>
#include <util/file.hpp>
+#include <util/filesystem.hpp>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
-#include <filesystem>
-
-namespace fs = std::filesystem;
+namespace fs = util::filesystem;
MiniTrace::MiniTrace(const ArgsInfo& args_info)
: m_args_info(args_info),
m_trace_id(reinterpret_cast<void*>(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());
#include <fmtmacros.hpp>
#include <util/TimePoint.hpp>
#include <util/file.hpp>
+#include <util/filesystem.hpp>
#include <util/path.hpp>
#include <util/string.hpp>
using IncludeDelimiter = util::Tokenizer::IncludeDelimiter;
-namespace fs = std::filesystem;
+namespace fs = util::filesystem;
namespace {
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
#include <util/environment.hpp>
#include <util/expected.hpp>
#include <util/file.hpp>
+#include <util/filesystem.hpp>
#include <util/path.hpp>
#include <util/process.hpp>
#include <util/string.hpp>
#include <fcntl.h>
-#include <filesystem>
#include <optional>
#include <string_view>
#include <memory>
#include <unordered_map>
-namespace fs = std::filesystem;
+namespace fs = util::filesystem;
using core::Statistic;
// 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
#include <util/TextTable.hpp>
#include <util/expected.hpp>
#include <util/file.hpp>
+#include <util/filesystem.hpp>
#include <util/process.hpp>
#include <util/string.hpp>
#include <algorithm>
#include <atomic>
#include <cstdlib>
-#include <filesystem>
#include <memory>
#include <numeric>
#include <string>
#include <utility>
-namespace fs = std::filesystem;
+namespace fs = util::filesystem;
using core::Statistic;
using core::StatisticsCounters;
// 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));
#endif
return;
}
- LOG("Failed to hard link {} to {}: {}", source, dest, ec.message());
- // Fall back to copying.
}
LOG("Copying {} to {}", source, dest);
#include <core/exceptions.hpp>
#include <core/wincompat.hpp>
#include <util/file.hpp>
+#include <util/filesystem.hpp>
#include "third_party/fmt/core.h"
const util::Duration k_staleness_limit(2);
#endif
-namespace fs = std::filesystem;
+namespace fs = util::filesystem;
namespace {
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?
--- /dev/null
+// 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 <third_party/nonstd/expected.hpp>
+
+#include <filesystem>
+
+namespace util::filesystem {
+
+using directory_iterator = std::filesystem::directory_iterator;
+using path = std::filesystem::path;
+
+#define DEFINE_FS_WRAPPER(name_, fnspec_) \
+ template<typename... Args> \
+ nonstd::expected<decltype(std::filesystem::name_ fnspec_), std::error_code> \
+ name_(Args&&... args) \
+ { \
+ std::error_code ec; \
+ if constexpr (std::is_same<decltype(std::filesystem::name_ fnspec_), \
+ void>::value) { \
+ std::filesystem::name_(std::forward<Args>(args)..., ec); \
+ if (ec) { \
+ return nonstd::make_unexpected(ec); \
+ } \
+ return {}; \
+ } else { \
+ auto result = std::filesystem::name_(std::forward<Args>(args)..., ec); \
+ if (ec) { \
+ return nonstd::make_unexpected(ec); \
+ } \
+ return result; \
+ } \
+ }
+
+#define DEFINE_FS_PREDICATE_WRAPPER(name_, fnspec_) \
+ template<typename... Args> bool name_(Args&&... args) \
+ { \
+ std::error_code ec; \
+ auto result = std::filesystem::name_(std::forward<Args>(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
#include <Util.hpp>
#include <fmtmacros.hpp>
+#include <util/filesystem.hpp>
#ifdef _WIN32
const char k_dev_null_path[] = "nul:";
const char k_path_delimiter[] = ":";
#endif
-namespace fs = std::filesystem;
+namespace fs = util::filesystem;
namespace util {
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<std::string>