return TRUE;
}
-/* A little helper to call unlinkat() as a cleanup
- * function. Mostly only necessary to handle
- * deletion of temporary symlinks.
- */
-typedef struct {
- int dfd;
- const char *path;
-} CleanupUnlinkat;
-
-static void
-cleanup_unlinkat (CleanupUnlinkat *cleanup)
-{
- if (cleanup->path)
- (void) unlinkat (cleanup->dfd, cleanup->path, 0);
-}
-G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(CleanupUnlinkat, cleanup_unlinkat);
-
/* Write a content object. */
static gboolean
write_content_object (OstreeRepo *self,
* temp_filename might also be a symlink. Hence the CleanupUnlinkat
* which handles that case.
*/
- g_auto(CleanupUnlinkat) tmp_unlinker = { self->tmp_dir_fd, NULL };
+ g_auto(OtCleanupUnlinkat) tmp_unlinker = { self->tmp_dir_fd, NULL };
glnx_fd_close int temp_fd = -1;
- g_autofree char *temp_filename = NULL;
gssize unpacked_size = 0;
gboolean indexable = FALSE;
if ((_ostree_repo_mode_is_bare (repo_mode)) && !phys_object_is_symlink)
guint64 size = g_file_info_get_size (file_info);
if (!create_regular_tmpfile_linkable_with_content (self, size, file_input,
- &temp_fd, &temp_filename,
+ &temp_fd, &tmp_unlinker.path,
cancellable, error))
return FALSE;
- tmp_unlinker.path = temp_filename;
}
else if (_ostree_repo_mode_is_bare (repo_mode) && phys_object_is_symlink)
{
regular file and take the branch above */
if (!_ostree_make_temporary_symlink_at (self->tmp_dir_fd,
g_file_info_get_symlink_target (file_info),
- &temp_filename,
+ &tmp_unlinker.path,
cancellable, error))
return FALSE;
- tmp_unlinker.path = temp_filename;
}
else if (repo_mode == OSTREE_REPO_MODE_ARCHIVE_Z2)
{
indexable = TRUE;
if (!glnx_open_tmpfile_linkable_at (self->tmp_dir_fd, ".", O_WRONLY|O_CLOEXEC,
- &temp_fd, &temp_filename,
+ &temp_fd, &tmp_unlinker.path,
error))
return FALSE;
- tmp_unlinker.path = temp_filename;
temp_out = g_unix_output_stream_new (temp_fd, FALSE);
file_meta = _ostree_zlib_file_header_new (file_info, xattrs);
const guint32 gid = g_file_info_get_attribute_uint32 (file_info, "unix::gid");
const guint32 mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
if (!commit_loose_content_object (self, actual_checksum,
- temp_filename,
+ tmp_unlinker.path,
object_file_type == G_FILE_TYPE_SYMBOLIC_LINK,
uid, gid, mode,
xattrs, temp_fd,
cancellable, error))
return glnx_prefix_error (error, "Writing object %s.%s", actual_checksum,
ostree_object_type_to_string (OSTREE_OBJECT_TYPE_FILE));
- /* Clear the unlinker path, it was consumed */
- tmp_unlinker.path = NULL;
+ /* Clear the unlinker, it was consumed */
+ ot_cleanup_unlinkat_clear (&tmp_unlinker);
/* Update size metadata if configured */
if (indexable && object_file_type == G_FILE_TYPE_REGULAR)
g_autoptr(GVariant) xattrs = NULL;
g_autoptr(GInputStream) file_in = NULL;
g_autoptr(GInputStream) object_input = NULL;
- g_autofree char *temp_path = NULL;
+ g_auto(OtCleanupUnlinkat) tmp_unlinker = { _ostree_fetcher_get_dfd (fetcher), NULL };
const char *checksum;
g_autofree char *checksum_obj = NULL;
OstreeObjectType objtype;
gboolean free_fetch_data = TRUE;
- if (!_ostree_fetcher_request_to_tmpfile_finish (fetcher, result, &temp_path, error))
+ if (!_ostree_fetcher_request_to_tmpfile_finish (fetcher, result, &tmp_unlinker.path, error))
goto out;
ostree_object_name_deserialize (fetch_data->object, &checksum, &objtype);
if (!have_object)
{
if (!_ostree_repo_commit_loose_final (pull_data->repo, checksum, OSTREE_OBJECT_TYPE_FILE,
- _ostree_fetcher_get_dfd (fetcher), -1, temp_path,
+ tmp_unlinker.dfd, -1, tmp_unlinker.path,
cancellable, error))
goto out;
+ /* The path was consumed */
+ ot_cleanup_unlinkat_clear (&tmp_unlinker);
}
pull_data->n_fetched_content++;
}
/* Non-mirroring path */
if (!ostree_content_file_parse_at (TRUE, _ostree_fetcher_get_dfd (fetcher),
- temp_path, FALSE,
+ tmp_unlinker.path, FALSE,
&file_in, &file_info, &xattrs,
cancellable, error))
- {
- /* If it appears corrupted, delete it */
- (void) unlinkat (_ostree_fetcher_get_dfd (fetcher), temp_path, 0);
- goto out;
- }
+ goto out;
/* Also, delete it now that we've opened it, we'll hold
* a reference to the fd. If we fail to validate or write, then
* the temp space will be cleaned up.
*/
- (void) unlinkat (_ostree_fetcher_get_dfd (fetcher), temp_path, 0);
+ ot_cleanup_unlinkat (&tmp_unlinker);
if (!validate_bareuseronly_mode (pull_data,
checksum,
FetchObjectData *fetch_data = user_data;
OtPullData *pull_data = fetch_data->pull_data;
g_autoptr(GVariant) metadata = NULL;
- g_autofree char *temp_path = NULL;
+ g_auto(OtCleanupUnlinkat) tmp_unlinker = { _ostree_fetcher_get_dfd (fetcher), NULL };
const char *checksum;
g_autofree char *checksum_obj = NULL;
OstreeObjectType objtype;
g_debug ("fetch of %s%s complete", checksum_obj,
fetch_data->is_detached_meta ? " (detached)" : "");
- if (!_ostree_fetcher_request_to_tmpfile_finish (fetcher, result, &temp_path, error))
+ if (!_ostree_fetcher_request_to_tmpfile_finish (fetcher, result, &tmp_unlinker.path, error))
{
if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
{
if (objtype == OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT)
goto out;
- fd = openat (_ostree_fetcher_get_dfd (fetcher), temp_path, O_RDONLY | O_CLOEXEC);
+ fd = openat (_ostree_fetcher_get_dfd (fetcher), tmp_unlinker.path, O_RDONLY | O_CLOEXEC);
if (fd == -1)
{
glnx_set_error_from_errno (error);
goto out;
}
+ /* Now delete it, keeping the fd open as the last reference); see comment in
+ * corresponding content fetch path.
+ */
+ ot_cleanup_unlinkat (&tmp_unlinker);
+
if (fetch_data->is_detached_meta)
{
if (!ot_util_variant_map_fd (fd, 0, G_VARIANT_TYPE ("a{sv}"),
FALSE, &metadata, error))
goto out;
- /* Now delete it, see comment in corresponding content fetch path */
- (void) unlinkat (_ostree_fetcher_get_dfd (fetcher), temp_path, 0);
-
if (!ostree_repo_write_commit_detached_metadata (pull_data->repo, checksum, metadata,
pull_data->cancellable, error))
goto out;
FALSE, &metadata, error))
goto out;
- (void) unlinkat (_ostree_fetcher_get_dfd (fetcher), temp_path, 0);
-
/* Write the commitpartial file now while we're still fetching data */
if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
{