From de09566b4a74de06a4cdf230538ed59d0ec2a465 Mon Sep 17 00:00:00 2001 From: Benau Date: Sat, 9 Apr 2022 14:59:57 +0800 Subject: [PATCH] Avoid configurations xml lost if having disk space issue, see #4709 --- src/config/player_manager.cpp | 6 +++- src/config/user_config.cpp | 5 +++- src/input/device_manager.cpp | 53 ++++++++++++++++++++-------------- src/network/server_config.cpp | 5 +++- src/race/highscore_manager.cpp | 10 +++++-- 5 files changed, 52 insertions(+), 27 deletions(-) diff --git a/src/config/player_manager.cpp b/src/config/player_manager.cpp index 56e8d56ab..ed1b04bcc 100644 --- a/src/config/player_manager.cpp +++ b/src/config/player_manager.cpp @@ -27,6 +27,7 @@ #include "io/xml_node.hpp" #include "online/online_player_profile.hpp" #include "race/race_manager.hpp" +#include "utils/file_utils.hpp" #include "utils/log.hpp" #include "utils/translation.hpp" @@ -250,7 +251,8 @@ void PlayerManager::save() std::string filename = file_manager->getUserConfigFile("players.xml"); try { - UTFWriter players_file(filename.c_str(), false); + // Save to a new file and rename later to avoid disk space problem, see #4709 + UTFWriter players_file((filename + "new").c_str(), false); players_file << "\n"; players_file << "\n"; @@ -269,6 +271,8 @@ void PlayerManager::save() } players_file << "\n"; players_file.close(); + file_manager->removeFile(filename); + FileUtils::renameU8Path(filename + "new", filename); } catch (std::runtime_error& e) { diff --git a/src/config/user_config.cpp b/src/config/user_config.cpp index 37f1c0e2a..31df64bae 100644 --- a/src/config/user_config.cpp +++ b/src/config/user_config.cpp @@ -742,10 +742,13 @@ void UserConfig::saveConfig() try { std::string s = ss.str(); - std::ofstream configfile(FileUtils::getPortableWritingPath(filename), + // Save to a new file and rename later to avoid disk space problem, see #4709 + std::ofstream configfile(FileUtils::getPortableWritingPath(filename + "new"), std::ofstream::out); configfile << ss.rdbuf(); configfile.close(); + file_manager->removeFile(filename); + FileUtils::renameU8Path(filename + "new", filename); } catch (std::runtime_error& e) { diff --git a/src/input/device_manager.cpp b/src/input/device_manager.cpp index c56f88182..094eb08c2 100644 --- a/src/input/device_manager.cpp +++ b/src/input/device_manager.cpp @@ -545,11 +545,11 @@ bool DeviceManager::load() // ----------------------------------------------------------------------------- void DeviceManager::save() { - static std::string filepath = file_manager->getUserConfigFile(INPUT_FILE_NAME); + std::string filepath = file_manager->getUserConfigFile(INPUT_FILE_NAME); if(UserConfigParams::logMisc()) Log::info("Device manager","Serializing input.xml..."); - - std::ofstream configfile(FileUtils::getPortableWritingPath(filepath)); + // Save to a new file and rename later to avoid disk space problem, see #4709 + std::ofstream configfile(FileUtils::getPortableWritingPath(filepath + "new")); if(!configfile.is_open()) { @@ -558,29 +558,40 @@ void DeviceManager::save() } - configfile << "\n\n"; - - configfile << "\n\n"; - - for(unsigned int n=0; n\n\n"; + + configfile << "\n\n"; + + for(unsigned int n=0; n\n"; + configfile.close(); + file_manager->removeFile(filepath); + FileUtils::renameU8Path(filepath + "new", filepath); } - for(unsigned int n=0; n\n"; - configfile.close(); if(UserConfigParams::logMisc()) Log::info("Device manager","Serialization complete."); } // save diff --git a/src/network/server_config.cpp b/src/network/server_config.cpp index f5e782d6d..375d8d3e9 100644 --- a/src/network/server_config.cpp +++ b/src/network/server_config.cpp @@ -186,10 +186,13 @@ void writeServerConfigToDisk() const std::string& config_xml = getServerConfigXML(); try { + // Save to a new file and rename later to avoid disk space problem, see #4709 std::ofstream configfile(FileUtils::getPortableWritingPath( - g_server_config_path), std::ofstream::out); + g_server_config_path + "new"), std::ofstream::out); configfile << config_xml; configfile.close(); + file_manager->removeFile(g_server_config_path); + FileUtils::renameU8Path(g_server_config_path + "new", g_server_config_path); } catch (std::runtime_error& e) { diff --git a/src/race/highscore_manager.cpp b/src/race/highscore_manager.cpp index 30c6025a1..1c198e72e 100644 --- a/src/race/highscore_manager.cpp +++ b/src/race/highscore_manager.cpp @@ -26,6 +26,7 @@ #include "io/utf_writer.hpp" #include "race/race_manager.hpp" #include "utils/constants.hpp" +#include "utils/file_utils.hpp" #include "utils/log.hpp" #include "utils/string_utils.hpp" #include "utils/translation.hpp" @@ -150,7 +151,8 @@ void HighscoreManager::saveHighscores() try { - UTFWriter highscore_file(m_filename.c_str(), false); + // Save to a new file and rename later to avoid disk space problem, see #4709 + UTFWriter highscore_file((m_filename + "new").c_str(), false); highscore_file << "\n"; highscore_file << "\n"; @@ -160,11 +162,13 @@ void HighscoreManager::saveHighscores() } highscore_file << "\n"; highscore_file.close(); + file_manager->removeFile(m_filename); + FileUtils::renameU8Path(m_filename + "new", m_filename); } catch(std::exception &e) { - Log::error("Highscore Manager","Problems saving highscores in '%s'\n", m_filename.c_str()); - puts(e.what()); + Log::error("Highscore Manager","Problems saving highscores in '%s' because %s", + m_filename.c_str(), e.what()); m_can_write=false; }