Save config to temp file and move into place

Fixes KartKrew/Kart#1020 by not trying to write over ringconfig until
we have successfully written the whole config out, then atomically
replacing the old config with the new one using C++17 FS.
This commit is contained in:
Eidolon 2024-02-17 15:40:58 -06:00
parent 796e2b9517
commit ad0ced4da0

View file

@ -20,6 +20,8 @@
#pragma GCC diagnostic ignored "-Wclobbered"
#endif
#include <filesystem>
#include <unistd.h>
#endif
@ -673,7 +675,7 @@ void M_FirstLoadConfig(void)
void M_SaveConfig(const char *filename)
{
FILE *f;
char *filepath;
char tmppath[2048];
// make sure not to write back the config until it's been correctly loaded
if (!gameconfig_loaded)
@ -691,17 +693,23 @@ void M_SaveConfig(const char *filename)
// append srb2home to beginning of filename
// but check if srb2home isn't already there, first
if (!strstr(filename, srb2home))
filepath = va(pandf,srb2home, filename);
else
filepath = Z_StrDup(filename);
f = fopen(filepath, "w");
// change it only if valid
if (f)
strcpy(configfile, filepath);
{
sprintf(tmppath, "%s" PATHSEP "%s.tmp", srb2home, filename);
}
else
{
CONS_Alert(CONS_ERROR, M_GetText("Couldn't save game config file %s\n"), filepath);
sprintf(tmppath, "%s", filename);
}
f = fopen(tmppath, "w");
// change it only if valid
if (f)
{
strcpy(configfile, tmppath);
}
else
{
CONS_Alert(CONS_ERROR, M_GetText("Couldn't save game config file %s\n"), tmppath);
return;
}
}
@ -713,7 +721,9 @@ void M_SaveConfig(const char *filename)
return;
}
f = fopen(configfile, "w");
sprintf(tmppath, "%s.tmp", configfile);
f = fopen(tmppath, "w");
if (!f)
{
CONS_Alert(CONS_ERROR, M_GetText("Couldn't save game config file %s\n"), configfile);
@ -738,6 +748,24 @@ void M_SaveConfig(const char *filename)
}
fclose(f);
{
// Atomically replace the old config once the new one has been written.
namespace fs = std::filesystem;
fs::path tmp{tmppath};
fs::path real{configfile};
try
{
fs::rename(tmp, real);
}
catch (const fs::filesystem_error& ex)
{
CONS_Alert(CONS_ERROR, M_GetText("Failed to move temp config file to real destination\n"));
}
}
}
// ==========================================================================