[gtk+/gtk-2-24] iconcache: Ensure we don't lose data on power loss
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/gtk-2-24] iconcache: Ensure we don't lose data on power loss
- Date: Mon, 22 Nov 2010 19:26:50 +0000 (UTC)
commit 058ff14ac83821bbc4f9baa84061a7759f5da486
Author: Colin Walters <walters verbum org>
Date: Fri Nov 19 15:46:51 2010 -0500
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.
https://bugzilla.gnome.org/show_bug.cgi?id=635307
gtk/updateiconcache.c | 42 +++++++++++++++++++++++++++++++++++-------
1 files changed, 35 insertions(+), 7 deletions(-)
---
diff --git a/gtk/updateiconcache.c b/gtk/updateiconcache.c
index 3b92701..09db4cc 100644
--- a/gtk/updateiconcache.c
+++ b/gtk/updateiconcache.c
@@ -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,18 +1513,23 @@ 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))
{
g_printerr (_("The generated cache was invalid.\n"));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]