summaryrefslogtreecommitdiffstats
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
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.
-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