[libgsystem] fileutils: Add gs_file_sync_data()



commit 660aa3e43f53d272508fc8fcd3eef62b426c59ae
Author: Colin Walters <walters verbum org>
Date:   Fri Jan 4 17:02:39 2013 -0500

    fileutils: Add gs_file_sync_data()
    
    It often occurs that I want to ensure file data is on disk so that
    updates can be atomic.

 gsystem-file-utils.c |   65 ++++++++++++++++++++++++++++++++++++++++++++++++++
 gsystem-file-utils.h |    4 +++
 2 files changed, 69 insertions(+), 0 deletions(-)
---
diff --git a/gsystem-file-utils.c b/gsystem-file-utils.c
index 546ff99..5e70c34 100644
--- a/gsystem-file-utils.c
+++ b/gsystem-file-utils.c
@@ -159,6 +159,71 @@ gs_file_map_readonly (GFile         *file,
   return ret;
 }
 
+static int
+close_nointr (int fd)
+{
+  int res;
+  do
+    res = close (fd);
+  while (G_UNLIKELY (res != 0 && errno == EINTR));
+  return res;
+}
+
+/**
+ * gs_file_sync_data:
+ * @file: a #GFile
+ * @cancellable:
+ * @error:
+ *
+ * Wraps the UNIX fdatasync() function, which ensures that the data in
+ * @file is on non-volatile storage.
+ */
+gboolean
+gs_file_sync_data (GFile          *file,
+                   GCancellable   *cancellable,
+                   GError        **error)
+{
+  gboolean ret = FALSE;
+  int res;
+  int fd = -1; 
+
+  fd = _open_fd_noatime (gs_file_get_path_cached (file));
+  if (fd < 0)
+    {
+      int errsv = errno;
+      g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno),
+                           g_strerror (errsv));
+      goto out;
+    }
+
+  do
+    res = fdatasync (fd);
+  while (G_UNLIKELY (res != 0 && errno == EINTR));
+  if (res != 0)
+    {
+      int errsv = errno;
+      g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno),
+                           g_strerror (errsv));
+      goto out;
+    }
+
+  res = close_nointr (fd);
+  if (res != 0)
+    {
+      int errsv = errno;
+      g_set_error_literal (error, G_IO_ERROR, g_io_error_from_errno (errno),
+                           g_strerror (errsv));
+      goto out;
+    }
+  fd = -1;
+  
+  ret = TRUE;
+ out:
+  if (fd != -1)
+    (void) close_nointr (fd);
+  return ret;
+}
+
 /**
  * gs_file_get_path_cached:
  *
diff --git a/gsystem-file-utils.h b/gsystem-file-utils.h
index bf07b3a..768cc0c 100644
--- a/gsystem-file-utils.h
+++ b/gsystem-file-utils.h
@@ -40,6 +40,10 @@ GBytes *gs_file_map_readonly (GFile         *file,
                               GCancellable  *cancellable,
                               GError       **error);
 
+gboolean gs_file_sync_data (GFile          *file,
+                            GCancellable   *cancellable,
+                            GError        **error);
+
 gboolean gs_file_rename (GFile          *from,
                          GFile          *to,
                          GCancellable   *cancellable,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]