Bug 511367 - add g_file_make_directory_with_parents.
authorRoss Burton <ross@burtonini.com>
Wed, 11 Jun 2008 15:48:06 +0000 (15:48 +0000)
committerRoss Burton <rburton@src.gnome.org>
Wed, 11 Jun 2008 15:48:06 +0000 (15:48 +0000)
2008-06-11  Ross Burton  <ross@burtonini.com>

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.

svn path=/trunk/; revision=7001

ChangeLog
gio/gfile.c
gio/gfile.h
gio/gio.symbols

index 6ea1d9e..571ba67 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-06-11  Ross Burton  <ross@burtonini.com>
+
+       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  <slomo@circular-chaos.org>
 
        Bug 531900 – Use __builtin_offsetof for G_STRUCT_OFFSET if building
index 3094b9a..7cb6d77 100644 (file)
@@ -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
@@ -2701,6 +2707,84 @@ g_file_make_directory (GFile         *file,
 }
 
 /**
+ * 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.
  * @symlink_value: a string with the value of the new symlink.
index d93fe67..2b9f35e 100644 (file)
@@ -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,
index 6a34fd4..9f44c07 100644 (file)
@@ -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