#include "gasyncresult.h"
#include "gioerror.h"
#include "glibintl.h"
-#include "gstrfuncsprivate.h"
/**
* ]|
* Common schemes include "file", "http", "ftp", etc.
*
+ * The scheme can be different from the one used to construct the #GFile,
+ * in that it might be replaced with one that is logically equivalent to the #GFile.
+ *
* This call does no blocking I/O.
*
- * Returns: a string containing the URI scheme for the given
- * #GFile. The returned string should be freed with g_free()
- * when no longer needed.
+ * Returns: (nullable): a string containing the URI scheme for the given
+ * #GFile or %NULL if the #GFile was constructed with an invalid URI. The
+ * returned string should be freed with g_free() when no longer needed.
*/
char *
g_file_get_uri_scheme (GFile *file)
*
* This call does no blocking I/O.
*
- * Returns: a string containing the #GFile's URI.
+ * Returns: a string containing the #GFile's URI. If the #GFile was constructed
+ * with an invalid URI, an invalid URI is returned.
* The returned string should be freed with g_free()
* when no longer needed.
*/
return info->flags & G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE;
}
-static gboolean
-build_attribute_list_for_copy (GFile *file,
- GFileCopyFlags flags,
- char **out_attributes,
- GCancellable *cancellable,
- GError **error)
+/**
+ * g_file_build_attribute_list_for_copy:
+ * @file: a #GFile to copy attributes to
+ * @flags: a set of #GFileCopyFlags
+ * @cancellable: (nullable): optional #GCancellable object,
+ * %NULL to ignore
+ * @error: a #GError, %NULL to ignore
+ *
+ * Prepares the file attribute query string for copying to @file.
+ *
+ * This function prepares an attribute query string to be
+ * passed to g_file_query_info() to get a list of attributes
+ * normally copied with the file (see g_file_copy_attributes()
+ * for the detailed description). This function is used by the
+ * implementation of g_file_copy_attributes() and is useful
+ * when one needs to query and set the attributes in two
+ * stages (e.g., for recursive move of a directory).
+ *
+ * Returns: an attribute query string for g_file_query_info(),
+ * or %NULL if an error occurs.
+ *
+ * Since: 2.68
+ */
+char *
+g_file_build_attribute_list_for_copy (GFile *file,
+ GFileCopyFlags flags,
+ GCancellable *cancellable,
+ GError **error)
{
- gboolean ret = FALSE;
+ char *ret = NULL;
GFileAttributeInfoList *attributes = NULL, *namespaces = NULL;
GString *s = NULL;
gboolean first;
gboolean copy_all_attributes;
gboolean skip_perms;
+ g_return_val_if_fail (G_IS_FILE (file), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
copy_all_attributes = flags & G_FILE_COPY_ALL_METADATA;
skip_perms = (flags & G_FILE_COPY_TARGET_DEFAULT_PERMS) != 0;
}
}
- ret = TRUE;
- *out_attributes = g_string_free (s, FALSE);
+ ret = g_string_free (s, FALSE);
s = NULL;
out:
if (s)
GFileInfo *info;
gboolean source_nofollow_symlinks;
- if (!build_attribute_list_for_copy (destination, flags, &attrs_to_read,
- cancellable, error))
+ attrs_to_read = g_file_build_attribute_list_for_copy (destination, flags,
+ cancellable, error);
+ if (!attrs_to_read)
return FALSE;
source_nofollow_symlinks = flags & G_FILE_COPY_NOFOLLOW_SYMLINKS;
char *attrs_to_read;
gboolean do_set_attributes = FALSE;
GFileCreateFlags create_flags;
+ GError *tmp_error = NULL;
/* need to know the file type */
info = g_file_query_info (source,
goto out;
in = G_INPUT_STREAM (file_in);
- if (!build_attribute_list_for_copy (destination, flags, &attrs_to_read,
- cancellable, error))
+ attrs_to_read = g_file_build_attribute_list_for_copy (destination, flags,
+ cancellable, error);
+ if (!attrs_to_read)
goto out;
- if (attrs_to_read != NULL)
- {
- GError *tmp_error = NULL;
+ /* Ok, ditch the previous lightweight info (on Unix we just
+ * called lstat()); at this point we gather all the information
+ * we need about the source from the opened file descriptor.
+ */
+ g_object_unref (info);
- /* Ok, ditch the previous lightweight info (on Unix we just
- * called lstat()); at this point we gather all the information
- * we need about the source from the opened file descriptor.
+ info = g_file_input_stream_query_info (file_in, attrs_to_read,
+ cancellable, &tmp_error);
+ if (!info)
+ {
+ /* Not all gvfs backends implement query_info_on_read(), we
+ * can just fall back to the pathname again.
+ * https://bugzilla.gnome.org/706254
*/
- g_object_unref (info);
-
- info = g_file_input_stream_query_info (file_in, attrs_to_read,
- cancellable, &tmp_error);
- if (!info)
+ if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
{
- /* Not all gvfs backends implement query_info_on_read(), we
- * can just fall back to the pathname again.
- * https://bugzilla.gnome.org/706254
- */
- if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
- {
- g_clear_error (&tmp_error);
- info = g_file_query_info (source, attrs_to_read, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- cancellable, error);
- }
- else
- {
- g_free (attrs_to_read);
- g_propagate_error (error, tmp_error);
- goto out;
- }
+ g_clear_error (&tmp_error);
+ info = g_file_query_info (source, attrs_to_read, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ cancellable, error);
+ }
+ else
+ {
+ g_free (attrs_to_read);
+ g_propagate_error (error, tmp_error);
+ goto out;
}
- g_free (attrs_to_read);
- if (!info)
- goto out;
-
- do_set_attributes = TRUE;
}
+ g_free (attrs_to_read);
+ if (!info)
+ goto out;
+
+ do_set_attributes = TRUE;
/* In the local file path, we pass down the source info which
* includes things like unix::mode, to ensure that the target file
/* Ignore errors here, we're only reading anyway */
g_output_stream_close_finish (stream, close_res, NULL);
- g_object_unref (stream);
if (!data->failed)
{
g_task_get_cancellable (data->task),
replace_contents_write_callback,
data);
+ g_object_unref (stream); /* ownership is transferred to the write_async() call above */
}
else
{
g_main_context_invoke_full (g_task_get_context (task),
g_task_get_priority (task),
measure_disk_usage_invoke_progress,
- g_memdup2 (&progress, sizeof progress),
+ g_memdup (&progress, sizeof progress),
g_free);
}
data->progress_callback ? measure_disk_usage_progress : NULL, task,
&result.disk_usage, &result.num_dirs, &result.num_files,
&error))
- g_task_return_pointer (task, g_memdup2 (&result, sizeof result), g_free);
+ g_task_return_pointer (task, g_memdup (&result, sizeof result), g_free);
else
g_task_return_error (task, error);
}
task = g_task_new (file, cancellable, callback, user_data);
g_task_set_source_tag (task, g_file_real_measure_disk_usage_async);
- g_task_set_task_data (task, g_memdup2 (&data, sizeof data), g_free);
+ g_task_set_task_data (task, g_memdup (&data, sizeof data), g_free);
g_task_set_priority (task, io_priority);
g_task_run_in_thread (task, measure_disk_usage_thread);