summaryrefslogtreecommitdiffstats
path: root/Settings.c
diff options
context:
space:
mode:
authorChristian Göttsche <cgzones@googlemail.com>2023-09-28 17:17:38 +0200
committerBenBE <BenBE@geshi.org>2023-11-11 21:51:53 +0100
commit5e8fc97a96dd2dea1aad8c6c4f2e872aede38ead (patch)
tree3b53856197cc8b7a9617891a1bff97b32ba99fde /Settings.c
parent69053ff77a1587eab52db64f923aa82672eb6018 (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.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/Settings.c b/Settings.c
index 16e1044f..ed60ff59 100644
--- a/Settings.c
+++ b/Settings.c
@@ -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;
}

© 2014-2024 Faster IT GmbH | imprint | privacy policy