]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
refactor: Use std::filesystem::create_director{ies,y}
authorJoel Rosdahl <joel@rosdahl.net>
Sun, 16 Jul 2023 08:22:06 +0000 (10:22 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Tue, 18 Jul 2023 19:36:01 +0000 (21:36 +0200)
src/Config.cpp
src/Util.cpp
src/Util.hpp
src/ccache.cpp
src/storage/remote/FileStorage.cpp
src/util/LockFile.cpp
src/util/filesystem.hpp
unittest/TestUtil.cpp
unittest/main.cpp
unittest/test_Util.cpp
unittest/test_storage_local_util.cpp

index ffb722f5db0621b53235b85696baa4dafc2ae622..38fa4432d8d074ef3d2456d705a03fe51bd78067 100644 (file)
@@ -33,6 +33,7 @@
 #include <util/environment.hpp>
 #include <util/expected.hpp>
 #include <util/file.hpp>
+#include <util/filesystem.hpp>
 #include <util/path.hpp>
 #include <util/string.hpp>
 
@@ -57,6 +58,8 @@ DLLIMPORT extern char** environ;
 // Make room for binary patching at install time.
 const char k_sysconfdir[4096 + 1] = SYSCONFDIR;
 
+namespace fs = util::filesystem;
+
 namespace {
 
 enum class ConfigItem {
@@ -1157,7 +1160,7 @@ Config::default_temporary_dir() const
     const char* const xdg_runtime_dir = getenv("XDG_RUNTIME_DIR");
     if (xdg_runtime_dir && Stat::stat(xdg_runtime_dir).is_directory()) {
       auto dir = FMT("{}/ccache-tmp", xdg_runtime_dir);
-      if (Util::create_dir(dir) && access(dir.c_str(), W_OK) == 0) {
+      if (fs::create_directories(dir) && access(dir.c_str(), W_OK) == 0) {
         return dir;
       }
     }
index af397ea01f71106f09a476702e5223d80bc39d7f..20b35cc57b24181d35837f514ef8dcf5b82a2f67 100644 (file)
@@ -186,34 +186,6 @@ common_dir_prefix_length(std::string_view dir, std::string_view path)
   return i;
 }
 
-bool
-create_dir(std::string_view dir)
-{
-  std::string dir_str(dir);
-  auto st = Stat::stat(dir_str);
-  if (st) {
-    if (st.is_directory()) {
-      return true;
-    } else {
-      errno = ENOTDIR;
-      return false;
-    }
-  } else {
-    if (!create_dir(Util::dir_name(dir))) {
-      return false;
-    }
-    int result = mkdir(dir_str.c_str(), 0777);
-    // Treat an already existing directory as OK since the file system could
-    // have changed in between calling stat and actually creating the
-    // directory. This can happen when there are multiple instances of ccache
-    // running and trying to create the same directory chain, which usually is
-    // the case when the cache root does not initially exist. As long as one of
-    // the processes creates the directories then our condition is satisfied
-    // and we avoid a race condition.
-    return result == 0 || errno == EEXIST;
-  }
-}
-
 std::string_view
 dir_name(std::string_view path)
 {
@@ -260,9 +232,9 @@ format_argv_for_logging(const char* const* argv)
 void
 ensure_dir_exists(std::string_view dir)
 {
-  if (!create_dir(dir)) {
+  if (auto result = fs::create_directories(dir); !result) {
     throw core::Fatal(
-      FMT("Failed to create directory {}: {}", dir, strerror(errno)));
+      FMT("Failed to create directory {}: {}", dir, result.error().message()));
   }
 }
 
index 5c47bf24956a9628543e6eaee0d78c699f09f128..1a79a1c926ef9d0088789e03d34e33130a989786 100644 (file)
@@ -51,11 +51,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);
 
-// Create a directory if needed, including its parents if needed.
-//
-// Returns true if the directory exists or could be created, otherwise false.
-bool create_dir(std::string_view dir);
-
 // Get directory name of path.
 std::string_view dir_name(std::string_view path);
 
index 8002f7ccc2be46ad5d64a75e7610e613c6d75710..0a67083510517c7605a44342a2f1e545089fc0b4 100644 (file)
@@ -190,10 +190,10 @@ prepare_debug_path(const std::string& debug_dir,
                   ? output_obj
                   : debug_dir + util::to_absolute_path_no_drive(output_obj);
 
-  // Ignore any error from create_dir since we can't handle an error in another
-  // way in this context. The caller takes care of logging when trying to open
-  // the path for writing.
-  Util::create_dir(Util::dir_name(prefix));
+  // Ignore any error from fs::create_directories since we can't handle an error
+  // in another way in this context. The caller takes care of logging when
+  // trying to open the path for writing.
+  fs::create_directories(Util::dir_name(prefix));
 
   char timestamp[100];
   const auto tm = Util::localtime(time_of_invocation);
index 917cb2b820b75d3dba88c70810d9ca5c5bd7bd57..0d3848eba79edd93a7c077365242b768d18a562b 100644 (file)
 #include <util/UmaskScope.hpp>
 #include <util/expected.hpp>
 #include <util/file.hpp>
+#include <util/filesystem.hpp>
 #include <util/string.hpp>
 
 #include <sys/stat.h> // for mode_t
 
 #include <string_view>
 
+namespace fs = util::filesystem;
+
 namespace storage::remote {
 
 namespace {
@@ -149,8 +152,8 @@ FileStorageBackend::put(const Hash::Digest& key,
     util::UmaskScope umask_scope(m_umask);
 
     const auto dir = Util::dir_name(path);
-    if (!Util::create_dir(dir)) {
-      LOG("Failed to create directory {}: {}", dir, strerror(errno));
+    if (auto result = fs::create_directories(dir); !result) {
+      LOG("Failed to create directory {}: {}", dir, result.error().message());
       return nonstd::make_unexpected(Failure::error);
     }
 
index 9fb998f45d7afd9427f5d71eddf2082ad52733ca..cfa3625d29d26bab936724fab433f122e37a7714 100644 (file)
@@ -247,7 +247,7 @@ LockFile::do_acquire(const bool blocking)
     int saved_errno = errno;
     if (saved_errno == ENOENT) {
       // Directory doesn't exist?
-      if (Util::create_dir(Util::dir_name(m_lock_file))) {
+      if (fs::create_directories(Util::dir_name(m_lock_file))) {
         // OK. Retry.
         continue;
       }
@@ -380,7 +380,7 @@ LockFile::do_acquire(const bool blocking)
     DWORD error = GetLastError();
     if (error == ERROR_PATH_NOT_FOUND) {
       // Directory doesn't exist?
-      if (Util::create_dir(Util::dir_name(m_lock_file))) {
+      if (fs::create_directories(Util::dir_name(m_lock_file))) {
         // OK. Retry.
         continue;
       }
index f780164b90cca42fc3392b7c5142bc86aaccfe28..03f990e26fca2ee44708b1119c93b228844230bd 100644 (file)
@@ -58,6 +58,8 @@ using path = std::filesystem::path;
   }
 
 DEFINE_FS_WRAPPER(canonical, (path{}))
+DEFINE_FS_WRAPPER(create_directories, (path{}))
+DEFINE_FS_WRAPPER(create_directory, (path{}))
 DEFINE_FS_WRAPPER(create_hard_link, (path{}, path{}))
 DEFINE_FS_WRAPPER(current_path, ())
 DEFINE_FS_WRAPPER(read_symlink, (path{}))
index ea8abc95200be3dffe1e4aff8426a8d1c224d204..0f07d0dc61b7b296278b14f6c799c66156f673d2 100644 (file)
@@ -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.
 //
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
 #include <fmtmacros.hpp>
+#include <util/filesystem.hpp>
 
 #ifdef HAVE_UNISTD_H
 #  include <unistd.h>
 #endif
 
+namespace fs = util::filesystem;
+
 namespace TestUtil {
 
 size_t TestContext::m_subdir_counter = 0;
@@ -39,7 +42,7 @@ TestContext::TestContext() : m_test_dir(Util::get_actual_cwd())
   }
   ++m_subdir_counter;
   std::string subtest_dir = FMT("{}/test_{}", m_test_dir, m_subdir_counter);
-  Util::create_dir(subtest_dir);
+  fs::create_directories(subtest_dir);
   if (chdir(subtest_dir.c_str()) != 0) {
     abort();
   }
index d67126f7189e20a274e07f1f704c5cd326640ccb..f2aab3ad4069d9df0cd7986ae8554fa0959a6f5d 100644 (file)
@@ -21,6 +21,7 @@
 #include "TestUtil.hpp"
 
 #include <util/environment.hpp>
+#include <util/filesystem.hpp>
 
 #include "third_party/fmt/core.h"
 
@@ -28,6 +29,8 @@
 #define DOCTEST_CONFIG_IMPLEMENT
 #include "third_party/doctest.h"
 
+namespace fs = util::filesystem;
+
 int
 main(int argc, char** argv)
 {
@@ -39,7 +42,7 @@ main(int argc, char** argv)
   std::string dir_before = Util::get_actual_cwd();
   std::string testdir = FMT("testdir/{}", getpid());
   Util::wipe_path(testdir);
-  Util::create_dir(testdir);
+  fs::create_directories(testdir);
   TestUtil::check_chdir(testdir);
 
   doctest::Context context;
index 331482aa987585b564774ffa7d545c64d2800e1a..195e1caf9fa2da27a4818fa6c244631d95c17001 100644 (file)
@@ -27,6 +27,7 @@
 #include <core/wincompat.hpp>
 #include <util/environment.hpp>
 #include <util/file.hpp>
+#include <util/filesystem.hpp>
 
 #include "third_party/doctest.h"
 
@@ -44,6 +45,8 @@
 
 using TestUtil::TestContext;
 
+namespace fs = util::filesystem;
+
 TEST_SUITE_BEGIN("Util");
 
 TEST_CASE("Util::base_name")
@@ -89,19 +92,6 @@ TEST_CASE("Util::common_dir_prefix_length")
   CHECK(Util::common_dir_prefix_length("/a/b", "/a/bc") == 2);
 }
 
-TEST_CASE("Util::create_dir")
-{
-  TestContext test_context;
-
-  CHECK(Util::create_dir("/"));
-
-  CHECK(Util::create_dir("create/dir"));
-  CHECK(Stat::stat("create/dir").is_directory());
-
-  util::write_file("create/dir/file", "");
-  CHECK(!Util::create_dir("create/dir/file"));
-}
-
 TEST_CASE("Util::dir_name")
 {
   CHECK(Util::dir_name("") == ".");
@@ -145,7 +135,7 @@ TEST_CASE("Util::ensure_dir_exists")
   util::write_file("create/dir/file", "");
   CHECK_THROWS_WITH(
     Util::ensure_dir_exists("create/dir/file"),
-    "Failed to create directory create/dir/file: Not a directory");
+    doctest::Contains("Failed to create directory create/dir/file:"));
 }
 
 TEST_CASE("Util::format_argv_for_logging")
@@ -265,7 +255,7 @@ TEST_CASE("Util::make_relative_path")
   const std::string apparent_cwd = FMT("{}/s", cwd);
 #endif
 
-  REQUIRE(Util::create_dir("d"));
+  REQUIRE(fs::create_directory("d"));
 #ifndef _WIN32
   REQUIRE(symlink("d", "s") == 0);
 #endif
@@ -388,7 +378,7 @@ TEST_CASE("Util::normalize_concrete_absolute_path")
   TestContext test_context;
 
   util::write_file("file", "");
-  REQUIRE(Util::create_dir("dir1/dir2"));
+  REQUIRE(fs::create_directories("dir1/dir2"));
   REQUIRE(symlink("dir1/dir2", "symlink") == 0);
   const auto cwd = Util::get_actual_cwd();
 
@@ -428,12 +418,12 @@ TEST_CASE("Util::traverse")
 {
   TestContext test_context;
 
-  REQUIRE(Util::create_dir("dir-with-subdir-and-file/subdir"));
+  REQUIRE(fs::create_directories("dir-with-subdir-and-file/subdir"));
   util::write_file("dir-with-subdir-and-file/subdir/f", "");
-  REQUIRE(Util::create_dir("dir-with-files"));
+  REQUIRE(fs::create_directory("dir-with-files"));
   util::write_file("dir-with-files/f1", "");
   util::write_file("dir-with-files/f2", "");
-  REQUIRE(Util::create_dir("empty-dir"));
+  REQUIRE(fs::create_directory("empty-dir"));
 
   std::vector<std::string> visited;
   auto visitor = [&visited](const std::string& path, bool is_dir) {
@@ -500,7 +490,7 @@ TEST_CASE("Util::wipe_path")
 
   SUBCASE("Wipe directory")
   {
-    REQUIRE(Util::create_dir("a/b"));
+    REQUIRE(fs::create_directories("a/b"));
     util::write_file("a/1", "");
     util::write_file("a/b/1", "");
     CHECK_NOTHROW(Util::wipe_path("a"));
index 5c3cce2d53f2095ab56bf23916b57cdc64916df5..b44468709782bed068877e72698c1f1d63bad5ed 100644 (file)
 
 #include "TestUtil.hpp"
 
-#include <Util.hpp>
 #include <fmtmacros.hpp>
 #include <storage/local/util.hpp>
 #include <util/file.hpp>
+#include <util/filesystem.hpp>
 
 #include <third_party/doctest.h>
 
@@ -31,6 +31,8 @@
 
 using TestUtil::TestContext;
 
+namespace fs = util::filesystem;
+
 static inline std::string
 os_path(std::string path)
 {
@@ -59,10 +61,10 @@ TEST_CASE("storage::local::get_cache_dir_files")
 {
   TestContext test_context;
 
-  Util::create_dir("e/m/p/t/y");
+  fs::create_directories("e/m/p/t/y");
 
-  Util::create_dir("0/1");
-  Util::create_dir("0/f/c");
+  fs::create_directories("0/1");
+  fs::create_directories("0/f/c");
   util::write_file("0/file_a", "");
   util::write_file("0/1/file_b", "1");
   util::write_file("0/1/file_c", "12");