Settings: check if writing configuration file was successful

Writing to the file stream might fail due to a immutable file or a
filesystem error.
Check the error indicator for the stream and for fclose() failures.
This commit is contained in:
Christian Göttsche 2021-03-12 16:56:06 +01:00
parent 350b48e44c
commit 521f1343e3
3 changed files with 16 additions and 8 deletions

View File

@ -7,6 +7,7 @@ in the source distribution for its full text.
#include "Settings.h" #include "Settings.h"
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
@ -280,10 +281,10 @@ static void writeMeterModes(const Settings* this, FILE* fd, int column) {
fprintf(fd, "\n"); fprintf(fd, "\n");
} }
bool Settings_write(const Settings* this) { int Settings_write(const Settings* this) {
FILE* fd = fopen(this->filename, "w"); FILE* fd = fopen(this->filename, "w");
if (fd == NULL) if (fd == NULL)
return false; return -errno;
fprintf(fd, "# Beware! This file is rewritten by htop when settings are changed in the interface.\n"); fprintf(fd, "# Beware! This file is rewritten by htop when settings are changed in the interface.\n");
fprintf(fd, "# The parser is also very primitive, and not human-friendly.\n"); fprintf(fd, "# The parser is also very primitive, and not human-friendly.\n");
@ -331,8 +332,10 @@ bool Settings_write(const Settings* this) {
#ifdef HAVE_LIBHWLOC #ifdef HAVE_LIBHWLOC
fprintf(fd, "topology_affinity=%d\n", (int) this->topologyAffinity); fprintf(fd, "topology_affinity=%d\n", (int) this->topologyAffinity);
#endif #endif
fclose(fd);
return true; int r1 = ferror(fd);
int r2 = fclose(fd);
return r1 ? r1 : r2;
} }
Settings* Settings_new(int initialCpuCount) { Settings* Settings_new(int initialCpuCount) {
@ -422,7 +425,7 @@ Settings* Settings_new(int initialCpuCount) {
ok = Settings_read(this, legacyDotfile, initialCpuCount); ok = Settings_read(this, legacyDotfile, initialCpuCount);
if (ok) { if (ok) {
// Transition to new location and delete old configuration file // Transition to new location and delete old configuration file
if (Settings_write(this)) { if (Settings_write(this) == 0) {
unlink(legacyDotfile); unlink(legacyDotfile);
} }
} }

View File

@ -87,7 +87,7 @@ static inline int Settings_getActiveDirection(const Settings* this) {
void Settings_delete(Settings* this); void Settings_delete(Settings* this);
bool Settings_write(const Settings* this); int Settings_write(const Settings* this);
Settings* Settings_new(int initialCpuCount); Settings* Settings_new(int initialCpuCount);

9
htop.c
View File

@ -482,8 +482,13 @@ int main(int argc, char** argv) {
Platform_done(); Platform_done();
CRT_done(); CRT_done();
if (settings->changed)
Settings_write(settings); if (settings->changed) {
int r = Settings_write(settings);
if (r < 0)
fprintf(stderr, "Can not save configuration to %s: %s\n", settings->filename, strerror(-r));
}
Header_delete(header); Header_delete(header);
ProcessList_delete(pl); ProcessList_delete(pl);