]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
fix: Log "bad output file" instead of "cache miss" on output file error
authorJoel Rosdahl <joel@rosdahl.net>
Tue, 19 Jul 2022 12:24:22 +0000 (14:24 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Tue, 19 Jul 2022 12:26:03 +0000 (14:26 +0200)
doc/MANUAL.adoc
src/ResultRetriever.cpp
src/ResultRetriever.hpp
src/ccache.cpp
test/suites/base.bash

index be147f68cb3f1ed6f2be9a0a0df745146a4c3598..0688108b90fbefafec41ebc1cc947c30b6e892bb 100644 (file)
@@ -1332,8 +1332,7 @@ Preconditions for using <<Precompiled headers,precompiled headers>> were not
 fulfilled.
 
 | Could not write to output file |
-The output path specified with `-o` is not a file (e.g. a directory or a device
-node).
+The output path specified with `-o` could not be written to.
 
 | Compilation failed |
 The compilation failed. No result stored in the cache.
index 6f079e1a916f800f002974715fba76c6feaa0532..6e84c82bc6746024a16e9f04a11e6a48d4225fed 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <core/exceptions.hpp>
 #include <core/wincompat.hpp>
+#include <fmtmacros.hpp>
 #include <util/file.hpp>
 
 #include <fcntl.h>
@@ -128,8 +129,8 @@ ResultRetriever::on_entry_start(uint8_t entry_number,
     m_dest_fd = Fd(
       open(dest_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666));
     if (!m_dest_fd) {
-      throw core::Error(
-        "Failed to open {} for writing: {}", dest_path, strerror(errno));
+      throw WriteError(
+        FMT("Failed to open {} for writing: {}", dest_path, strerror(errno)));
     }
     m_dest_path = dest_path;
   }
@@ -150,7 +151,7 @@ ResultRetriever::on_entry_data(const uint8_t* data, size_t size)
     try {
       Util::write_fd(*m_dest_fd, data, size);
     } catch (core::Error& e) {
-      throw core::Error("Failed to write to {}: {}", m_dest_path, e.what());
+      throw WriteError(FMT("Failed to write to {}: {}", m_dest_path, e.what()));
     }
   }
 }
@@ -195,6 +196,6 @@ ResultRetriever::write_dependency_file()
                    m_dest_data.data() + start_pos,
                    m_dest_data.length() - start_pos);
   } catch (core::Error& e) {
-    throw core::Error("Failed to write to {}: {}", m_dest_path, e.what());
+    throw WriteError(FMT("Failed to write to {}: {}", m_dest_path, e.what()));
   }
 }
index 27c13f9b3a50d4d635ac5a5bc79db3a95fdbcb2a..bdd4f893bb5b462cd4c2180a9d7a9e63450de183 100644 (file)
 #include "Fd.hpp"
 #include "Result.hpp"
 
+#include <core/exceptions.hpp>
+
 class Context;
 
 // This class retrieves a result entry to the local file system.
 class ResultRetriever : public Result::Reader::Consumer
 {
 public:
+  class WriteError : public core::Error
+  {
+    using core::Error::Error;
+  };
+
   ResultRetriever(Context& ctx, bool rewrite_dependency_target);
 
   void on_entry_start(uint8_t entry_number,
index f494378514a640589861879ed4b5267a5212d99e..ef1b67a8eaa5400f485fb9c2234fdce9477a7f21 100644 (file)
@@ -1883,7 +1883,7 @@ calculate_result_and_manifest_key(Context& ctx,
 enum class FromCacheCallMode { direct, cpp };
 
 // Try to return the compile result from cache.
-static bool
+static nonstd::expected<bool, Failure>
 from_cache(Context& ctx, FromCacheCallMode mode, const Digest& result_key)
 {
   UmaskScope umask_scope(ctx.original_umask);
@@ -1926,6 +1926,10 @@ from_cache(Context& ctx, FromCacheCallMode mode, const Digest& result_key)
       ctx, should_rewrite_dependency_target(ctx.args_info));
 
     result_reader.read(result_retriever);
+  } catch (ResultRetriever::WriteError& e) {
+    LOG(
+      "Write error when retrieving result from {}: {}", *result_path, e.what());
+    return nonstd::make_unexpected(Statistic::bad_output_file);
   } catch (core::Error& e) {
     LOG("Failed to get result from {}: {}", *result_path, e.what());
     return false;
@@ -2305,9 +2309,11 @@ do_cache_compilation(Context& ctx, const char* const* argv)
     std::tie(result_key, manifest_key) = *result_and_manifest_key;
     if (result_key) {
       // If we can return from cache at this point then do so.
-      const bool found =
+      const auto from_cache_result =
         from_cache(ctx, FromCacheCallMode::direct, *result_key);
-      if (found) {
+      if (!from_cache_result) {
+        return nonstd::make_unexpected(from_cache_result.error());
+      } else if (*from_cache_result) {
         return Statistic::direct_cache_hit;
       }
 
@@ -2372,8 +2378,11 @@ do_cache_compilation(Context& ctx, const char* const* argv)
     }
 
     // If we can return from cache at this point then do.
-    const auto found = from_cache(ctx, FromCacheCallMode::cpp, *result_key);
-    if (found) {
+    const auto from_cache_result =
+      from_cache(ctx, FromCacheCallMode::cpp, *result_key);
+    if (!from_cache_result) {
+      return nonstd::make_unexpected(from_cache_result.error());
+    } else if (*from_cache_result) {
       if (ctx.config.direct_mode() && manifest_key && put_result_in_manifest) {
         update_manifest_file(ctx, *manifest_key, *result_key);
       }
index 5cbef4c37c207cea3fbf4d1316a23785a838246b..88186a7276b6543dcf57091678629f204d395463 100644 (file)
@@ -1184,6 +1184,24 @@ EOF
     expect_stat preprocessed_cache_hit 1
     expect_stat cache_miss 1
 
+    # -------------------------------------------------------------------------
+    TEST "Failure to write output file"
+
+    mkdir dir
+
+    $CCACHE_COMPILE -c test1.c -o dir/test1.o
+    expect_stat preprocessed_cache_hit 0
+    expect_stat cache_miss 1
+    expect_stat bad_output_file 0
+
+    rm dir/test1.o
+    chmod a-w dir
+
+    $CCACHE_COMPILE -c test1.c -o dir/test1.o 2>/dev/null
+    expect_stat preprocessed_cache_hit 0
+    expect_stat cache_miss 1
+    expect_stat bad_output_file 1
+
     # -------------------------------------------------------------------------
     TEST "Caching stderr"