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.
#include <core/exceptions.hpp>
#include <core/wincompat.hpp>
+#include <fmtmacros.hpp>
#include <util/file.hpp>
#include <fcntl.h>
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;
}
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()));
}
}
}
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()));
}
}
#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,
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);
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;
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;
}
}
// 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);
}
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"