diff options
author | Christian Göttsche <cgzones@googlemail.com> | 2023-09-28 17:17:38 +0200 |
---|---|---|
committer | BenBE <BenBE@geshi.org> | 2023-11-11 21:51:53 +0100 |
commit | 5e8fc97a96dd2dea1aad8c6c4f2e872aede38ead (patch) | |
tree | 3b53856197cc8b7a9617891a1bff97b32ba99fde /Settings.c | |
parent | 69053ff77a1587eab52db64f923aa82672eb6018 (diff) |
Write configuration to temporary file first
Currently when the runtime configuration is saved to file the true
configuration file is first truncated and then written to with each
available option.
If for any reason htop dies (e.g. program crash, or system shutdown)
while still performing the output the configuration file might end up
empty or corrupted.
Write to a temporary file and rename at the end on success.
As a side effect new configuration files are now created with a mode of
0600.
Diffstat (limited to 'Settings.c')
-rw-r--r-- | Settings.c | 12 |
1 files changed, 11 insertions, 1 deletions
@@ -603,11 +603,16 @@ static void writeMeterModes(const Settings* this, FILE* fd, char separator, unsi int Settings_write(const Settings* this, bool onCrash) { FILE* fd; char separator; + char *tmpFilename = NULL; if (onCrash) { fd = stderr; separator = ';'; } else { - fd = fopen(this->filename, "w"); + xAsprintf(&tmpFilename, "%s.tmp.XXXXXX", this->filename); + int fdtmp = mkstemp(tmpFilename); + if (fdtmp == -1) + return -errno; + fd = fdopen(fdtmp, "w"); if (fd == NULL) return -errno; separator = '\n'; @@ -719,6 +724,11 @@ int Settings_write(const Settings* this, bool onCrash) { if (fclose(fd) != 0) r = r ? r : -errno; + if (r == 0) + r = (rename(tmpFilename, this->filename) == -1) ? -errno : 0; + + free(tmpFilename); + return r; } |