]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
fix: Make sure that temporary files always have .tmp. in the name
authorJoel Rosdahl <joel@rosdahl.net>
Mon, 12 Sep 2022 11:25:45 +0000 (13:25 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 21 Sep 2022 15:06:30 +0000 (17:06 +0200)
PrimaryStorage::clean_dir relies on being able to classify temporary
files from the filename.

src/AtomicFile.cpp
src/TemporaryFile.cpp
src/TemporaryFile.hpp
src/Util.cpp
src/ccache.cpp
src/storage/primary/PrimaryStorage_cleanup.cpp

index ec5fead6e76eb5fbe1ae34909e4b3068b6e65f1b..c9d82c3e2728a2599fdf1499d455598b550889e1 100644 (file)
@@ -27,7 +27,7 @@
 
 AtomicFile::AtomicFile(const std::string& path, Mode mode) : m_path(path)
 {
-  TemporaryFile tmp_file(path + ".tmp");
+  TemporaryFile tmp_file(path);
   m_stream = fdopen(tmp_file.fd.release(), mode == Mode::binary ? "w+b" : "w+");
   m_tmp_path = std::move(tmp_file.path);
 }
index 0d7e80bfb9bf0488e0eeca2d4cd6bdec1cb73f80..257481234499b80ea6fd950c394d7df11b4da14f 100644 (file)
@@ -35,7 +35,7 @@
 
 TemporaryFile::TemporaryFile(std::string_view path_prefix,
                              std::string_view suffix)
-  : path(FMT("{}.XXXXXX{}", path_prefix, suffix))
+  : path(FMT("{}{}XXXXXX{}", path_prefix, tmp_file_infix, suffix))
 {
   Util::ensure_dir_exists(Util::dir_name(path));
 #ifdef _WIN32
@@ -59,3 +59,9 @@ TemporaryFile::TemporaryFile(std::string_view path_prefix,
   fchmod(*fd, 0666 & ~Util::get_umask());
 #endif
 }
+
+bool
+TemporaryFile::is_tmp_file(std::string_view path)
+{
+  return Util::base_name(path).find(tmp_file_infix) != std::string::npos;
+}
index 29d8597e3e3e167cddbb07c344d9e539a76061e9..b773c0a4b203c19a1f2193dcc6c19b66c5d5fff5 100644 (file)
 class TemporaryFile
 {
 public:
+  static constexpr char tmp_file_infix[] = ".tmp.";
+
   // `path_prefix` is the base path. The resulting filename will be this path
-  //  plus a unique string plus `suffix`. If `path_prefix` refers to a
-  //  nonexistent directory the directory will be created if possible.`
-  TemporaryFile(std::string_view path_prefix, std::string_view suffix = {});
+  // plus a unique string plus `suffix`. If `path_prefix` refers to a
+  // nonexistent directory the directory will be created if possible.
+  TemporaryFile(std::string_view path_prefix, std::string_view suffix = ".tmp");
 
   TemporaryFile(TemporaryFile&& other) noexcept = default;
 
   TemporaryFile& operator=(TemporaryFile&& other) noexcept = default;
 
+  static bool is_tmp_file(std::string_view path);
+
   // The resulting open file descriptor in read/write mode. Unset on error.
   Fd fd;
 
index 179bbc7f629281538596730e2ada13162f3e90b0..8b0b6e0ec58591f9ba2951f4dcd1cd664e8b4985 100644 (file)
@@ -1315,7 +1315,8 @@ unlink_safe(const std::string& path, UnlinkLog unlink_log)
   // If path is on an NFS share, unlink isn't atomic, so we rename to a temp
   // file. We don't care if the temp file is trashed, so it's always safe to
   // unlink it first.
-  std::string tmp_name = path + ".ccache.rm.tmp";
+  const std::string tmp_name =
+    FMT("{}.ccache{}unlink", path, TemporaryFile::tmp_file_infix);
 
   bool success = true;
   try {
index 0d1c4b027b5064871aac10956b09ebeacb2eec87..4a10147e3c6ad93ea783068875db084c9de23cd0 100644 (file)
@@ -679,7 +679,7 @@ get_tmp_fd(Context& ctx,
 {
   if (capture_output) {
     TemporaryFile tmp_stdout(
-      FMT("{}/tmp.{}", ctx.config.temporary_dir(), description));
+      FMT("{}/{}", ctx.config.temporary_dir(), description));
     ctx.register_pending_tmp_file(tmp_stdout.path);
     return {std::move(tmp_stdout.fd), std::move(tmp_stdout.path)};
   } else {
@@ -1158,9 +1158,8 @@ get_result_key_from_cpp(Context& ctx, Args& args, Hash& hash)
 
     // preprocessed_path needs the proper cpp_extension for the compiler to do
     // its thing correctly.
-    TemporaryFile tmp_stdout(
-      FMT("{}/tmp.cpp_stdout", ctx.config.temporary_dir()),
-      FMT(".{}", ctx.config.cpp_extension()));
+    TemporaryFile tmp_stdout(FMT("{}/cpp_stdout", ctx.config.temporary_dir()),
+                             FMT(".{}", ctx.config.cpp_extension()));
     preprocessed_path = tmp_stdout.path;
     tmp_stdout.fd.close(); // We're only using the path.
     ctx.register_pending_tmp_file(preprocessed_path);
index d3a0b1b93349d639801f6473ddd4c9d6fff1be19..6165c724d6f488bab4cf14437037a1d250911bec 100644 (file)
@@ -23,6 +23,7 @@
 #include <Context.hpp>
 #include <File.hpp>
 #include <Logging.hpp>
+#include <TemporaryFile.hpp>
 #include <Util.hpp>
 #include <core/CacheEntry.hpp>
 #include <core/exceptions.hpp>
@@ -124,7 +125,7 @@ PrimaryStorage::clean_dir(const std::string& subdir,
 
     // Delete any tmp files older than 1 hour right away.
     if (file.lstat().mtime() + 3600 < current_time
-        && Util::base_name(file.path()).find(".tmp.") != std::string::npos) {
+        && TemporaryFile::is_tmp_file(file.path())) {
       Util::unlink_tmp(file.path());
       continue;
     }