Commit 6c6b4939 authored by Colin Walters's avatar Colin Walters Committed by Javier Jardón

iconcache: Ensure we don't lose data on power loss

fsync() should ensure our data hits disk; since corrupt icon
caches break all apps, we need to ensure it's valid.

Fixes https://bugzilla.gnome.org/show_bug.cgi?id=635307
parent 323df2b2
......@@ -1424,6 +1424,30 @@ validate_file (const gchar *file)
return TRUE;
}
/**
* safe_fclose:
* @f: A FILE* stream, must have underlying fd
*
* Unix defaults for data preservation after system crash
* are unspecified, and many systems will eat your data
* in this situation unless you explicitly fsync().
*
* Returns: %TRUE on success, %FALSE on failure, and will set errno()
*/
static gboolean
safe_fclose (FILE *f)
{
int fd = fileno (f);
g_assert (fd >= 0);
if (fflush (f) == EOF)
return FALSE;
if (fsync (fd) < 0)
return FALSE;
if (fclose (f) == EOF)
return FALSE;
return TRUE;
}
static void
build_cache (const gchar *path)
{
......@@ -1432,7 +1456,6 @@ build_cache (const gchar *path)
gchar *bak_cache_path = NULL;
#endif
GHashTable *files;
gboolean retval;
FILE *cache;
struct stat path_stat, cache_stat;
struct utimbuf utime_buf;
......@@ -1490,17 +1513,22 @@ opentmp:
}
/* FIXME: Handle failure */
retval = write_file (cache, files, directories);
fclose (cache);
if (!write_file (cache, files, directories))
{
g_unlink (tmp_cache_path);
exit (1);
}
g_list_foreach (directories, (GFunc)g_free, NULL);
g_list_free (directories);
if (!retval)
if (!safe_fclose (cache))
{
g_printerr (_("Failed to write cache file: %s\n"), g_strerror (errno));
g_unlink (tmp_cache_path);
exit (1);
}
cache = NULL;
g_list_foreach (directories, (GFunc)g_free, NULL);
g_list_free (directories);
if (!validate_file (tmp_cache_path))
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment