Make writing files a bit safer
Especially configuration files.
This commit is contained in:
parent
9e3cb2b6aa
commit
60dd23ab8f
22
liberty.c
22
liberty.c
@ -3379,11 +3379,11 @@ write_file (const char *filename, const struct str *data, struct error **e)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
fwrite (data->str, data->len, 1, fp);
|
fwrite (data->str, data->len, 1, fp);
|
||||||
|
bool success = !ferror (fp) && !fflush (fp) && !fsync (fileno (fp));
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
|
|
||||||
if (errno)
|
if (!success)
|
||||||
{
|
{
|
||||||
error_set (e, "writing to `%s' failed: %s", filename, strerror (errno));
|
error_set (e, "writing to `%s' failed: %s", filename, strerror (errno));
|
||||||
return false;
|
return false;
|
||||||
@ -3391,6 +3391,22 @@ write_file (const char *filename, const struct str *data, struct error **e)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wrapper for write_file() that makes sure that the new data has been written
|
||||||
|
/// to disk in its entirety before overriding the old file
|
||||||
|
static bool
|
||||||
|
write_file_safe (const char *filename, const struct str *data, struct error **e)
|
||||||
|
{
|
||||||
|
// XXX: ideally we would also open the directory, use *at() versions
|
||||||
|
// of functions and call fsync() on the directory as appropriate
|
||||||
|
char *temp = xstrdup_printf ("%s.new", filename);
|
||||||
|
bool success = write_file (temp, data, e);
|
||||||
|
if (success && !(success = !rename (temp, filename)))
|
||||||
|
error_set (e, "could not rename `%s' to `%s': %s",
|
||||||
|
temp, filename, strerror (errno));
|
||||||
|
free (temp);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
// --- Simple configuration ----------------------------------------------------
|
// --- Simple configuration ----------------------------------------------------
|
||||||
|
|
||||||
// The keys are stripped of surrounding whitespace, the values are not.
|
// The keys are stripped of surrounding whitespace, the values are not.
|
||||||
@ -3482,7 +3498,7 @@ write_configuration_file (const char *path_hint, const struct str *data,
|
|||||||
str_append (&path, "/" PROGRAM_NAME "/" PROGRAM_NAME ".conf");
|
str_append (&path, "/" PROGRAM_NAME "/" PROGRAM_NAME ".conf");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!write_file (path.str, data, e))
|
if (!write_file_safe (path.str, data, e))
|
||||||
{
|
{
|
||||||
str_free (&path);
|
str_free (&path);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user