#include <core/exceptions.hpp>
#include <fmtmacros.hpp>
#include <util/file.hpp>
+#include <util/filesystem.hpp>
+
+namespace fs = util::filesystem;
AtomicFile::AtomicFile(const std::string& path, Mode mode) : m_path(path)
{
throw core::Error(
FMT("failed to write data to {}: {}", m_path, strerror(errno)));
}
- const auto result = util::rename(m_tmp_path, m_path);
+ const auto result = fs::rename(m_tmp_path, m_path);
if (!result) {
throw core::Error(FMT("failed to rename {} to {}: {}",
m_tmp_path,
src_fd.close();
if (via_tmp_file) {
- const auto result = util::rename(tmp_file, dest);
+ const auto result = fs::rename(tmp_file, dest);
if (!result) {
throw core::Error(FMT("failed to rename {} to {}: {}",
tmp_file,
// Note: Two ccache processes may move the file at the same time, so failure
// to rename is OK.
LOG("Moving {} to {}", cache_file_path, wanted_path);
- util::rename(cache_file_path, wanted_path);
+ fs::rename(cache_file_path, wanted_path);
for (const auto& raw_file : m_added_raw_files) {
- util::rename(
+ fs::rename(
raw_file,
FMT("{}/{}", Util::dir_name(wanted_path), Util::base_name(raw_file)));
}
UmaskScope.cpp
environment.cpp
file.cpp
+ filesystem.cpp
path.cpp
process.cpp
string.cpp
src_fd.close();
if (via_tmp_file == ViaTmpFile::yes) {
- const auto result = util::rename(tmp_file, dest);
+ const auto result = fs::rename(tmp_file, dest);
if (!result) {
return nonstd::make_unexpected(FMT("Failed to rename {} to {}: {}",
tmp_file,
std::string tmp_name =
FMT("{}.ccache{}remove", path, TemporaryFile::tmp_file_infix);
- auto rename_result = util::rename(path, tmp_name);
+ auto rename_result = fs::rename(path, tmp_name);
if (!rename_result) {
// It's OK if it was removed in a race.
if (rename_result.error().value() != ENOENT
return remove_result;
}
-nonstd::expected<void, std::error_code>
-rename(const std::string& oldpath, const std::string& newpath)
-{
-#ifndef _WIN32
- std::error_code ec;
- std::filesystem::rename(oldpath, newpath, ec);
- if (ec) {
- return nonstd::make_unexpected(ec);
- }
-#else
- // Windows' rename() won't overwrite an existing file, so need to use
- // MoveFileEx instead.
- if (!MoveFileExA(
- oldpath.c_str(), newpath.c_str(), MOVEFILE_REPLACE_EXISTING)) {
- DWORD error = GetLastError();
- // TODO: How should the Win32 error be mapped to std::error_code?
- return nonstd::make_unexpected(
- std::error_code(error, std::system_category()));
- }
-#endif
- return {};
-}
-
void
set_timestamps(const std::string& path,
std::optional<util::TimePoint> mtime,
remove_nfs_safe(const std::string& path,
LogFailure log_failure = LogFailure::yes);
-// Rename `oldpath` to `newpath` (deleting `newpath`).
-//
-// Note: Mingw-w64's std::filesystem::rename is buggy and doesn't properly
-// overwrite an existing file, at least in version 9.1.0, hence this utility
-// function.
-nonstd::expected<void, std::error_code> rename(const std::string& oldpath,
- const std::string& newpath);
-
// Set the FD_CLOEXEC on file descriptor `fd`. This is a NOP on Windows.
void set_cloexec_flag(int fd);
--- /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
+
+#include "filesystem.hpp"
+
+#include <core/wincompat.hpp>
+
+namespace util::filesystem {
+
+nonstd::expected<void, std::error_code>
+rename(const std::filesystem::path& old_p, const std::filesystem::path& new_p)
+{
+#ifndef _WIN32
+ std::error_code ec;
+ std::filesystem::rename(old_p, new_p, ec);
+ if (ec) {
+ return nonstd::make_unexpected(ec);
+ }
+#else
+ // Windows' rename() won't overwrite an existing file, so need to use
+ // MoveFileEx instead.
+ if (!MoveFileExA(old_p.string().c_str(),
+ new_p.string().c_str(),
+ MOVEFILE_REPLACE_EXISTING)) {
+ DWORD error = GetLastError();
+ // TODO: How should the Win32 error be mapped to std::error_code?
+ return nonstd::make_unexpected(
+ std::error_code(error, std::system_category()));
+ }
+#endif
+ return {};
+}
+
+} // namespace util::filesystem
DEF_WRAP_1_R(read_symlink, path, const path&, p)
DEF_WRAP_1_R(remove, bool, const path&, p)
DEF_WRAP_1_R(remove_all, std::uintmax_t, const path&, p)
-// Note: Use util::rename instead of fs::rename.
DEF_WRAP_0_R(temp_directory_path, path)
// clang-format on
#undef DEF_WRAP_1_V
#undef DEF_WRAP_2_V
+// Note: Mingw-w64's std::filesystem::rename is buggy and doesn't properly
+// overwrite an existing file, at least in version 9.1.0, hence this custom
+// wrapper.
+nonstd::expected<void, std::error_code> rename(const path& old_p,
+ const path& new_p);
+
} // namespace util::filesystem