From 5e8fc97a96dd2dea1aad8c6c4f2e872aede38ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Thu, 28 Sep 2023 17:17:38 +0200 Subject: 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. --- Settings.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'Settings.c') 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; } -- cgit v1.2.3