diff --git a/ChangeLog b/ChangeLog index 6ea1d9ef0..571ba6749 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-06-11 Ross Burton + + Bug 511367 - add g_file_make_directory_with_parents. + + * gio/gfile.c: + * gio/gfile.h: + * gio/gio.symbols: Add g_file_make_directory_with_parents. + 2008-06-11 Sebastian Dröge Bug 531900 – Use __builtin_offsetof for G_STRUCT_OFFSET if building diff --git a/gio/gfile.c b/gio/gfile.c index 3094b9ab9..7cb6d7749 100644 --- a/gio/gfile.c +++ b/gio/gfile.c @@ -2667,7 +2667,13 @@ g_file_move (GFile *source, * @cancellable: optional #GCancellable object, %NULL to ignore. * @error: a #GError, or %NULL * - * Creates a directory. + * Creates a directory. Note that this will only create a child directory of + * the immediate parent directory of the path or URI given by the #GFile. To + * recursively create directories, see g_file_make_directory_with_parents(). + * This function will fail if the parent directory does not exist, setting + * @error to %G_IO_ERROR_NOT_FOUND. If the file system doesn't support creating + * directories, this function will fail, setting @error to + * %G_IO_ERROR_NOT_SUPPORTED. * * If @cancellable is not %NULL, then the operation can be cancelled by * triggering the cancellable object from another thread. If the operation @@ -2700,6 +2706,84 @@ g_file_make_directory (GFile *file, return (* iface->make_directory) (file, cancellable, error); } +/** + * g_file_make_directory_with_parents: + * @file: input #GFile. + * @cancellable: optional #GCancellable object, %NULL to ignore. + * @error: a #GError, or %NULL + * + * Creates a directory and any parent directories that may not exist similar to + * 'mkdir -p'. If the file system does not support creating directories, this + * function will fail, setting @error to %G_IO_ERROR_NOT_SUPPORTED. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the cancellable object from another thread. If the operation + * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. + * + * Returns: %TRUE if all directories have been successfully created, %FALSE + * otherwise. + * + * Since: 2.18 + **/ +gboolean +g_file_make_directory_with_parents (GFile *file, + GCancellable *cancellable, + GError **error) +{ + gboolean result; + GFile *parent_file, *work_file; + GList *list = NULL, *l; + GError *my_error = NULL; + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + result = g_file_make_directory (file, cancellable, &my_error); + if (result || my_error->code != G_IO_ERROR_NOT_FOUND) + { + if (my_error) + g_propagate_error (error, my_error); + return result; + } + + work_file = file; + + while (!result && my_error->code == G_IO_ERROR_NOT_FOUND) + { + g_clear_error (&my_error); + + parent_file = g_file_get_parent (work_file); + if (parent_file == NULL) + break; + result = g_file_make_directory (parent_file, cancellable, &my_error); + + if (!result && my_error->code == G_IO_ERROR_NOT_FOUND) + list = g_list_prepend (list, parent_file); + + work_file = parent_file; + } + + for (l = list; result && l; l = l->next) + { + result = g_file_make_directory ((GFile *) l->data, cancellable, &my_error); + } + + /* Clean up */ + while (list != NULL) + { + g_object_unref ((GFile *) list->data); + list = g_list_remove (list, list->data); + } + + if (!result) + { + g_propagate_error (error, my_error); + return result; + } + + return g_file_make_directory (file, cancellable, error); +} + /** * g_file_make_symbolic_link: * @file: input #GFile. diff --git a/gio/gfile.h b/gio/gfile.h index d93fe6738..2b9f35edd 100644 --- a/gio/gfile.h +++ b/gio/gfile.h @@ -751,6 +751,9 @@ gboolean g_file_move (GFile gboolean g_file_make_directory (GFile *file, GCancellable *cancellable, GError **error); +gboolean g_file_make_directory_with_parents (GFile *file, + GCancellable *cancellable, + GError **error); gboolean g_file_make_symbolic_link (GFile *file, const char *symlink_value, GCancellable *cancellable, diff --git a/gio/gio.symbols b/gio/gio.symbols index 6a34fd430..9f44c07b4 100644 --- a/gio/gio.symbols +++ b/gio/gio.symbols @@ -274,6 +274,7 @@ g_file_copy_async g_file_copy_finish g_file_move g_file_make_directory +g_file_make_directory_with_parents g_file_make_symbolic_link g_file_query_settable_attributes g_file_query_writable_namespaces