patch_engine: make save_patches write atomically

save_patches opened the target with fs::rewrite (write + create + trunc),
then discarded the result of file.write() and returned true unconditionally.
A write that fails part way leaves a truncated file, load() rejects the
whole file on a parse error, and import_patches refuses to write when
load() fails, so every later import returns -1 with no in-app recovery.

75e66ab5e made the patch config and the pad config atomic but missed this
function; save_config, 70 lines up in the same file, already writes through
fs::pending_file and checks the result. Do the same here.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Antonino Di Guardo
2026-09-24 13:45:26 +02:00
committed by Megamouse
co-authored by Claude Opus 5
parent c82221f292
commit dc3c7327d8
+8 -3
View File
@@ -1805,8 +1805,9 @@ static void append_patches(patch_engine::patch_map& existing_patches, const patc
bool patch_engine::save_patches(const patch_map& patches, const std::string& path, std::stringstream* log_messages)
{
fs::file file(path, fs::rewrite);
if (!file)
fs::pending_file file(path);
if (!file.file)
{
append_log_message(log_messages, fmt::format("Failed to open patch file %s (%s)", path, fs::g_tls_error), &patch_log.fatal);
return false;
@@ -1920,7 +1921,11 @@ bool patch_engine::save_patches(const patch_map& patches, const std::string& pat
out << YAML::EndMap;
file.write(out.c_str(), out.size());
if (file.file.write(out.c_str(), out.size()) < out.size() || !file.commit())
{
append_log_message(log_messages, fmt::format("Failed to write patch file %s (%s)", path, fs::g_tls_error), &patch_log.fatal);
return false;
}
return true;
}