[[noreturn]] void
print_fatal_error_and_exit()
{
- // Note: Can't call fatal() since that would lead to recursion.
+ // Note: Can't throw FatalError since that would lead to recursion.
fmt::print(stderr,
"ccache: error: Failed to write to {}: {}\n",
logfile_path,
if (!initialize(path_prefix) && errno == ENOENT) {
auto dir = Util::dir_name(path);
if (!Util::create_dir(dir)) {
- fatal("Failed to create directory {}: {}", dir, strerror(errno));
+ throw FatalError(
+ "Failed to create directory {}: {}", dir, strerror(errno));
}
initialize(path_prefix);
}
if (!fd) {
- fatal("Failed to create temporary file for {}: {}", path, strerror(errno));
+ throw FatalError(
+ "Failed to create temporary file for {}: {}", path, strerror(errno));
}
Util::set_cloexec_flag(*fd);
}
}
#endif
- fatal("Could not determine home directory from $HOME or getpwuid(3)");
+ throw FatalError(
+ "Could not determine home directory from $HOME or getpwuid(3)");
}
const char*
for (const auto& word : Util::split_into_strings(prefix_command, " ")) {
std::string path = find_executable(ctx, word, MYNAME);
if (path.empty()) {
- fatal("{}: {}", word, strerror(errno));
+ throw FatalError("{}: {}", word, strerror(errno));
}
prefix.push_back(path);
std::string compiler = find_executable(ctx, base, MYNAME);
if (compiler.empty()) {
- fatal("Could not find compiler \"{}\" in PATH", base);
+ throw FatalError("Could not find compiler \"{}\" in PATH", base);
}
if (compiler == argv[0]) {
- fatal("Recursive invocation (the name of the ccache binary must be \"{}\")",
- MYNAME);
+ throw FatalError(
+ "Recursive invocation (the name of the ccache binary must be \"{}\")",
+ MYNAME);
}
ctx.orig_args[0] = compiler;
}
MTR_END("config", "conf_read_secondary");
if (config.cache_dir().empty()) {
- fatal("configuration setting \"cache_dir\" must not be the empty string");
+ throw FatalError(
+ "configuration setting \"cache_dir\" must not be the empty string");
}
if ((p = getenv("CCACHE_DIR"))) {
config.set_cache_dir(p);
}
if (config.cache_dir().empty()) {
- fatal("CCACHE_DIR must not be the empty string");
+ throw FatalError("CCACHE_DIR must not be the empty string");
}
config.set_primary_config_path(
log("Executing {}", Util::format_argv_for_logging(execv_argv.data()));
ctx.reset(); // Dump debug logs last thing before executing.
execv(execv_argv[0], const_cast<char* const*>(execv_argv.data()));
- fatal("execv of {} failed: {}", execv_argv[0], strerror(errno));
+ throw FatalError("execv of {} failed: {}", execv_argv[0], strerror(errno));
}
}
// with a non-zero exit code.
class FatalError : public ErrorBase
{
- using ErrorBase::ErrorBase;
+public:
+ // Special case: If given only one string, don't parse it as a format string.
+ FatalError(const std::string& message);
+
+ // `args` are forwarded to `fmt::format`.
+ template<typename... T> inline FatalError(T&&... args);
};
+inline FatalError::FatalError(const std::string& message) : ErrorBase(message)
+{
+}
+
+template<typename... T>
+inline FatalError::FatalError(T&&... args)
+ : ErrorBase(fmt::format(std::forward<T>(args)...))
+{
+}
+
// Throw a Failure if ccache did not succeed in getting or putting a result in
// the cache. If `exit_code` is set, just exit with that code directly,
// otherwise execute the real compiler and exit with its exit code. Also updates
{
return m_stat;
}
-
-// Something went badly wrong! Print a message to stderr and exit with non-zero
-// exit code. `args` are forwarded to `fmt::format`.
-template<typename... T>
-[[noreturn]] inline void
-fatal(T&&... args)
-{
- throw FatalError(fmt::format(std::forward<T>(args)...));
-}
}
if (*pid == -1) {
- fatal("Failed to fork: {}", strerror(errno));
+ throw FatalError("Failed to fork: {}", strerror(errno));
}
if (*pid == 0) {
int status;
if (waitpid(*pid, &status, 0) != *pid) {
- fatal("waitpid failed: {}", strerror(errno));
+ throw FatalError("waitpid failed: {}", strerror(errno));
}
{
#else
int pipefd[2];
if (pipe(pipefd) == -1) {
- fatal("pipe failed: {}", strerror(errno));
+ throw FatalError("pipe failed: {}", strerror(errno));
}
pid_t pid = fork();
if (pid == -1) {
- fatal("fork failed: {}", strerror(errno));
+ throw FatalError("fork failed: {}", strerror(errno));
}
if (pid == 0) {