diff options
author | Colin Walters <walters@verbum.org> | 2011-11-18 09:37:25 -0500 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2011-11-18 09:37:25 -0500 |
commit | 7276e2df434b1d8b4a9abe3a3920420a82102600 (patch) | |
tree | a54b44a3dd898cd60615cdb4a2f0f756ee048ca8 | |
parent | 860c3cf502226d093ba291b2ae90d3f1044598ef (diff) | |
download | ostree-7276e2df434b1d8b4a9abe3a3920420a82102600.tar.gz |
core: Have single "overwrite" flag instead of ignore_exists+force pair
The default is always ignore_exists. Also port the internals here
to use more GIO code, and stop using *at syscall variants since they're
only useful if used 100%.
-rw-r--r-- | src/libostree/ostree-repo.c | 142 | ||||
-rw-r--r-- | src/libostree/ostree-repo.h | 3 |
2 files changed, 55 insertions, 90 deletions
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 4e113e69..d6c9ecd5 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -645,7 +645,7 @@ import_gvariant_object (OstreeRepo *self, if (!ostree_repo_store_object_trusted (self, ot_gfile_get_path_cached (tmp_path), g_checksum_get_string (ret_checksum), OSTREE_OBJECT_TYPE_META, - TRUE, FALSE, &did_exist, error)) + FALSE, &did_exist, error)) goto out; ret = TRUE; @@ -783,88 +783,48 @@ link_object_trusted (OstreeRepo *self, const char *path, const char *checksum, OstreeObjectType objtype, - gboolean ignore_exists, - gboolean force, + gboolean overwrite, gboolean *did_exist, GError **error) { - char *src_basename = NULL; - char *src_dirname = NULL; - char *dest_basename = NULL; - char *tmp_dest_basename = NULL; - char *dest_dirname = NULL; - DIR *src_dir = NULL; - DIR *dest_dir = NULL; gboolean ret = FALSE; + char *dest_basename = NULL; + char *tmp_dest_path = NULL; const char *dest_path = NULL; GFile *dest_file = NULL; - src_basename = g_path_get_basename (path); - src_dirname = g_path_get_dirname (path); - - src_dir = opendir (src_dirname); - if (src_dir == NULL) - { - ot_util_set_error_from_errno (error, errno); - goto out; - } - if (!prepare_dir_for_checksum_get_object_path (self, checksum, objtype, &dest_file, error)) goto out; - dest_path = ot_gfile_get_path_cached (dest_file); - - dest_basename = g_path_get_basename (dest_path); - dest_dirname = g_path_get_dirname (dest_path); - dest_dir = opendir (dest_dirname); - if (dest_dir == NULL) - { - ot_util_set_error_from_errno (error, errno); - goto out; - } - if (force) + *did_exist = g_file_query_exists (dest_file, NULL); + if (!overwrite && *did_exist) { - tmp_dest_basename = g_strconcat (dest_basename, ".tmp", NULL); - (void) unlinkat (dirfd (dest_dir), tmp_dest_basename, 0); + ; } else - tmp_dest_basename = g_strdup (dest_basename); - - if (linkat (dirfd (src_dir), src_basename, dirfd (dest_dir), tmp_dest_basename, 0) < 0) { - if (errno != EEXIST || !ignore_exists) - { - ot_util_set_error_from_errno (error, errno); - goto out; - } - else - *did_exist = TRUE; - } - else - *did_exist = FALSE; + dest_path = ot_gfile_get_path_cached (dest_file); + dest_basename = g_path_get_basename (dest_path); + tmp_dest_path = g_strconcat (dest_path, ".tmp", NULL); - if (force) - { - if (renameat (dirfd (dest_dir), tmp_dest_basename, - dirfd (dest_dir), dest_basename) < 0) + (void) unlink (tmp_dest_path); + + if (link (path, tmp_dest_path) < 0 + || rename (tmp_dest_path, dest_path) < 0) { ot_util_set_error_from_errno (error, errno); goto out; } - (void) unlinkat (dirfd (dest_dir), tmp_dest_basename, 0); + g_free (tmp_dest_path); + tmp_dest_path = NULL; } ret = TRUE; out: - if (src_dir != NULL) - closedir (src_dir); - if (dest_dir != NULL) - closedir (dest_dir); - g_free (src_basename); - g_free (src_dirname); g_free (dest_basename); - g_free (tmp_dest_basename); - g_free (dest_dirname); + if (tmp_dest_path) + (void) unlink (tmp_dest_path); + g_free (tmp_dest_path); g_clear_object (&dest_file); return ret; } @@ -874,50 +834,57 @@ archive_file_trusted (OstreeRepo *self, const char *path, const char *checksum, OstreeObjectType objtype, - gboolean ignore_exists, - gboolean force, + gboolean overwrite, gboolean *did_exist, GError **error) { GFile *infile = NULL; - GFile *outfile = NULL; GFileOutputStream *out = NULL; gboolean ret = FALSE; - const char *dest_path = NULL; GFile *dest_file = NULL; - char *dest_tmp_path = NULL; + GError *temp_error = NULL; infile = ot_gfile_new_for_path (path); if (!prepare_dir_for_checksum_get_object_path (self, checksum, objtype, &dest_file, error)) goto out; - dest_path = ot_gfile_get_path_cached (dest_file); - - dest_tmp_path = g_strconcat (dest_path, ".tmp", NULL); - - outfile = ot_gfile_new_for_path (dest_tmp_path); - out = g_file_replace (outfile, NULL, FALSE, 0, NULL, error); - if (!out) - goto out; - if (!ostree_pack_object ((GOutputStream*)out, infile, objtype, NULL, error)) - goto out; - - if (!g_output_stream_close ((GOutputStream*)out, NULL, error)) - goto out; + if (overwrite) + { + out = g_file_replace (dest_file, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, error); + if (!out) + goto out; + } + else + { + out = g_file_create (dest_file, 0, NULL, &temp_error); + if (!out) + { + if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_EXISTS)) + { + g_clear_error (&temp_error); + } + else + { + g_propagate_error (error, temp_error); + goto out; + } + } + } - if (rename (dest_tmp_path, dest_path) < 0) + if (out) { - ot_util_set_error_from_errno (error, errno); - goto out; + if (!ostree_pack_object ((GOutputStream*)out, infile, objtype, NULL, error)) + goto out; + + if (!g_output_stream_close ((GOutputStream*)out, NULL, error)) + goto out; } ret = TRUE; out: g_clear_object (&dest_file); - g_free (dest_tmp_path); g_clear_object (&infile); - g_clear_object (&outfile); g_clear_object (&out); return ret; } @@ -927,16 +894,15 @@ ostree_repo_store_object_trusted (OstreeRepo *self, const char *path, const char *checksum, OstreeObjectType objtype, - gboolean ignore_exists, - gboolean force, + gboolean overwrite, gboolean *did_exist, GError **error) { OstreeRepoPrivate *priv = GET_PRIVATE (self); if (priv->archive && objtype == OSTREE_OBJECT_TYPE_FILE) - return archive_file_trusted (self, path, checksum, objtype, ignore_exists, force, did_exist, error); + return archive_file_trusted (self, path, checksum, objtype, overwrite, did_exist, error); else - return link_object_trusted (self, path, checksum, objtype, ignore_exists, force, did_exist, error); + return link_object_trusted (self, path, checksum, objtype, overwrite, did_exist, error); } gboolean @@ -969,7 +935,7 @@ ostree_repo_store_packfile (OstreeRepo *self, if (!ostree_repo_store_object_trusted (self, tempfile_path ? tempfile_path->str : path, expected_checksum, objtype, - TRUE, FALSE, did_exist, error)) + FALSE, did_exist, error)) goto out; ret = TRUE; @@ -1234,7 +1200,7 @@ add_one_file_to_tree_and_import (OstreeRepo *self, goto out; if (!ostree_repo_store_object_trusted (self, abspath, g_checksum_get_string (checksum), - OSTREE_OBJECT_TYPE_FILE, TRUE, FALSE, &did_exist, error)) + OSTREE_OBJECT_TYPE_FILE, FALSE, &did_exist, error)) goto out; g_hash_table_replace (tree->files, g_strdup (basename), diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index ec65bd94..7f6e27d8 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -80,8 +80,7 @@ gboolean ostree_repo_store_object_trusted (OstreeRepo *self, const char *path, const char *checksum, OstreeObjectType objtype, - gboolean ignore_exists, - gboolean force, + gboolean overwrite, gboolean *did_exist, GError **error); |