gboolean gs_dfd_and_name_set_all_xattrs (int dfd, const char *name, GVariant *xattrs, GCancellable *cancellable, GError **error) { return glnx_dfd_name_set_all_xattrs (dfd, name, xattrs, cancellable, error); }
/** * gs_file_set_all_xattrs: * @file: File descriptor * @xattrs: Extended attributes * @cancellable: Cancellable * @error: Error * * For each attribute in @xattrs, set its value on the file or * directory referred to by @file. This function does not remove any * attributes not in @xattrs. */ gboolean gs_file_set_all_xattrs (GFile *file, GVariant *xattrs, GCancellable *cancellable, GError **error) { return glnx_dfd_name_set_all_xattrs (AT_FDCWD, gs_file_get_path_cached (file), xattrs, cancellable, error); }
/* * This function creates a file under a temporary name, then rename()s * it into place. This implements union-like behavior. */ static gboolean checkout_file_unioning_from_input_at (OstreeRepo *repo, OstreeRepoCheckoutOptions *options, GFileInfo *file_info, GVariant *xattrs, GInputStream *input, int destination_dfd, const char *destination_name, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autofree char *temp_filename = NULL; if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK) { if (!_ostree_make_temporary_symlink_at (destination_dfd, g_file_info_get_symlink_target (file_info), &temp_filename, cancellable, error)) goto out; if (xattrs) { if (!glnx_dfd_name_set_all_xattrs (destination_dfd, temp_filename, xattrs, cancellable, error)) goto out; } } else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR) { g_autoptr(GOutputStream) temp_out = NULL; guint32 file_mode; file_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode"); /* Don't make setuid files on checkout when we're doing --user */ if (options->mode == OSTREE_REPO_CHECKOUT_MODE_USER) file_mode &= ~(S_ISUID|S_ISGID); if (!gs_file_open_in_tmpdir_at (destination_dfd, file_mode, &temp_filename, &temp_out, cancellable, error)) goto out; if (!write_regular_file_content (repo, options, temp_out, file_info, xattrs, input, cancellable, error)) goto out; } else g_assert_not_reached (); if (G_UNLIKELY (renameat (destination_dfd, temp_filename, destination_dfd, destination_name) == -1)) { glnx_set_error_from_errno (error); goto out; } ret = TRUE; out: return ret; }
static gboolean checkout_file_from_input_at (OstreeRepo *self, OstreeRepoCheckoutOptions *options, GFileInfo *file_info, GVariant *xattrs, GInputStream *input, int destination_dfd, const char *destination_name, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; int res; if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK) { do res = symlinkat (g_file_info_get_symlink_target (file_info), destination_dfd, destination_name); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (res == -1) { glnx_set_error_from_errno (error); goto out; } if (options->mode != OSTREE_REPO_CHECKOUT_MODE_USER) { if (G_UNLIKELY (fchownat (destination_dfd, destination_name, g_file_info_get_attribute_uint32 (file_info, "unix::uid"), g_file_info_get_attribute_uint32 (file_info, "unix::gid"), AT_SYMLINK_NOFOLLOW) == -1)) { glnx_set_error_from_errno (error); goto out; } if (xattrs) { if (!glnx_dfd_name_set_all_xattrs (destination_dfd, destination_name, xattrs, cancellable, error)) goto out; } } } else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR) { g_autoptr(GOutputStream) temp_out = NULL; int fd; guint32 file_mode; file_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode"); /* Don't make setuid files on checkout when we're doing --user */ if (options->mode == OSTREE_REPO_CHECKOUT_MODE_USER) file_mode &= ~(S_ISUID|S_ISGID); do fd = openat (destination_dfd, destination_name, O_WRONLY | O_CREAT | O_EXCL, file_mode); while (G_UNLIKELY (fd == -1 && errno == EINTR)); if (fd == -1) { glnx_set_error_from_errno (error); goto out; } temp_out = g_unix_output_stream_new (fd, TRUE); fd = -1; /* Transfer ownership */ if (!write_regular_file_content (self, options, temp_out, file_info, xattrs, input, cancellable, error)) goto out; } else g_assert_not_reached (); ret = TRUE; out: return ret; }