[libgsystem] fileutils: Add gs_file_sync_data()
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgsystem] fileutils: Add gs_file_sync_data()
- Date: Fri, 4 Jan 2013 22:17:11 +0000 (UTC)
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]