[ostree/wip/bootloader: 2/4] gioutils: Many new utility functions
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree/wip/bootloader: 2/4] gioutils: Many new utility functions
- Date: Sat, 29 Jun 2013 16:05:00 +0000 (UTC)
commit 9a9c8c0a045bdc0479e807acaba2c5e5aec52668
Author: Colin Walters <walters verbum org>
Date: Sat Jun 29 11:43:31 2013 -0400
gioutils: Many new utility functions
Reading symbolic links becomes a much more common thing now.
src/libotutil/ot-gio-utils.c | 207 ++++++++++++++++++++++++++++++++++++++++++
src/libotutil/ot-gio-utils.h | 37 ++++++++
2 files changed, 244 insertions(+), 0 deletions(-)
---
diff --git a/src/libotutil/ot-gio-utils.c b/src/libotutil/ot-gio-utils.c
index d37beeb..49d1a51 100644
--- a/src/libotutil/ot-gio-utils.c
+++ b/src/libotutil/ot-gio-utils.c
@@ -132,3 +132,210 @@ ot_gfile_get_child_build_path (GFile *parent,
return g_file_resolve_relative_path (parent, path);
}
+
+GFile *
+ot_gfile_resolve_path_printf (GFile *path,
+ const char *format,
+ ...)
+{
+ va_list args;
+ gs_free char *relpath = NULL;
+
+ va_start (args, format);
+ relpath = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ return g_file_resolve_relative_path (path, relpath);
+}
+
+
+gboolean
+ot_gfile_get_symlink_target_from_info (GFile *path,
+ GFileInfo *file_info,
+ GFile **out_target,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ const char *target;
+ gs_unref_object GFile *path_parent = NULL;
+ gs_unref_object GFile *ret_target = NULL;
+
+ if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_SYMBOLIC_LINK)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Not a symbolic link");
+ goto out;
+ }
+
+ path_parent = g_file_get_parent (path);
+ target = g_file_info_get_symlink_target (file_info);
+ g_assert (target);
+ ret_target = g_file_resolve_relative_path (path_parent, target);
+
+ ret = TRUE;
+ out:
+ ot_transfer_out_value (out_target, &ret_target);
+ return ret;
+}
+
+gboolean
+ot_gfile_query_info_allow_noent (GFile *path,
+ const char *queryopts,
+ GFileQueryInfoFlags flags,
+ GFileInfo **out_info,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ gs_unref_object GFileInfo *ret_file_info = NULL;
+ GError *temp_error = NULL;
+
+ ret_file_info = g_file_query_info (path, queryopts, flags,
+ cancellable, &temp_error);
+ if (!ret_file_info)
+ {
+ if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ {
+ g_clear_error (&temp_error);
+ }
+ else
+ {
+ g_propagate_error (error, temp_error);
+ goto out;
+ }
+ }
+
+ ret = TRUE;
+ ot_transfer_out_value (out_info, &ret_file_info);
+ out:
+ return ret;
+}
+
+gboolean
+ot_gfile_query_symlink_target_allow_noent (GFile *path,
+ GFile **out_target,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ gs_unref_object GFileInfo *file_info = NULL;
+ gs_unref_object GFile *ret_target = NULL;
+
+ if (!ot_gfile_query_info_allow_noent (path, OSTREE_GIO_FAST_QUERYINFO,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ &file_info,
+ cancellable, error))
+ goto out;
+
+ if (file_info != NULL)
+ {
+ if (!ot_gfile_get_symlink_target_from_info (path, file_info, &ret_target,
+ cancellable, error))
+ goto out;
+ }
+
+ ret = TRUE;
+ ot_transfer_out_value (out_target, &ret_target);
+ out:
+ return ret;
+}
+
+gboolean
+ot_gfile_load_contents_utf8_allow_noent (GFile *path,
+ char **out_contents,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = TRUE;
+ GError *temp_error = NULL;
+ gs_free char *ret_contents = NULL;
+
+ ret_contents = gs_file_load_contents_utf8 (path, cancellable, &temp_error);
+ if (!ret_contents)
+ {
+ if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ {
+ g_clear_error (&temp_error);
+ }
+ else
+ {
+ g_propagate_error (error, temp_error);
+ goto out;
+ }
+ }
+
+ ret = TRUE;
+ ot_transfer_out_value (out_contents, &ret_contents);
+ out:
+ return ret;
+}
+
+/**
+ * ot_gfile_ensure_unlinked:
+ *
+ * Like gs_file_unlink(), but return successfully if the file doesn't
+ * exist.
+ */
+gboolean
+ot_gfile_ensure_unlinked (GFile *path,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GError *temp_error = NULL;
+
+ if (!gs_file_unlink (path, cancellable, &temp_error))
+ {
+ if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ {
+ g_clear_error (&temp_error);
+ }
+ else
+ {
+ g_propagate_error (error, temp_error);
+ goto out;
+ }
+ }
+
+ ret = TRUE;
+ out:
+ return ret;
+}
+
+/**
+ * ot_gfile_atomic_symlink_swap:
+ * @path: Replace the contents of this symbolic link
+ * @target: New symbolic link target
+ * @cancellable:
+ * @error
+ *
+ * Create a new temporary symbolic link, then use the Unix rename()
+ * function to atomically replace @path with the new symbolic link.
+ * Do not use this function inside directories such as /tmp as it uses
+ * a predicatable file name.
+ */
+gboolean
+ot_gfile_atomic_symlink_swap (GFile *path,
+ const char *target,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ gs_unref_object GFile *parent = g_file_get_parent (path);
+ gs_free char *tmpname = g_strconcat (gs_file_get_basename_cached (path), ".tmp", NULL);
+ gs_unref_object GFile *tmppath = g_file_get_child (parent, tmpname);
+
+ if (!ot_gfile_ensure_unlinked (tmppath, cancellable, error))
+ goto out;
+
+ if (!g_file_make_symbolic_link (tmppath, target, cancellable, error))
+ goto out;
+
+ if (!gs_file_rename (tmppath, path, cancellable, error))
+ goto out;
+
+ ret = TRUE;
+ out:
+ return ret;
+}
diff --git a/src/libotutil/ot-gio-utils.h b/src/libotutil/ot-gio-utils.h
index 802602d..5ebf04a 100644
--- a/src/libotutil/ot-gio-utils.h
+++ b/src/libotutil/ot-gio-utils.h
@@ -42,6 +42,43 @@ GFile *ot_gfile_get_child_strconcat (GFile *parent, const char *first, ...) G_GN
GFile *ot_gfile_get_child_build_path (GFile *parent, const char *first, ...) G_GNUC_NULL_TERMINATED;
+GFile * ot_gfile_resolve_path_printf (GFile *path,
+ const char *format,
+ ...) G_GNUC_PRINTF(2, 3);
+
+
+gboolean ot_gfile_get_symlink_target_from_info (GFile *path,
+ GFileInfo *file_info,
+ GFile **out_target,
+ GCancellable *cancellable,
+ GError **error);
+
+gboolean ot_gfile_query_info_allow_noent (GFile *path,
+ const char *queryopts,
+ GFileQueryInfoFlags flags,
+ GFileInfo **out_info,
+ GCancellable *cancellable,
+ GError **error);
+
+gboolean ot_gfile_query_symlink_target_allow_noent (GFile *path,
+ GFile **out_target,
+ GCancellable *cancellable,
+ GError **error);
+
+gboolean ot_gfile_load_contents_utf8_allow_noent (GFile *path,
+ char **out_contents,
+ GCancellable *cancellable,
+ GError **error);
+
+gboolean ot_gfile_ensure_unlinked (GFile *path,
+ GCancellable *cancellable,
+ GError **error);
+
+gboolean ot_gfile_atomic_symlink_swap (GFile *path,
+ const char *target,
+ GCancellable *cancellable,
+ GError **error);
+
G_END_DECLS
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]