From 4f3ab40c042d8c53e8540188a7508e91301baa41 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 2 Dec 2014 12:34:30 -0500 Subject: [PATCH] gfile: Explain nonobvious use of my_error In g_file_make_directory_with_parents(), the my_error variable is used for several different purposes throughout the whole function, not all of which are obvious. This explains the situation with some comments. https://bugzilla.gnome.org/show_bug.cgi?id=719455 --- gio/gfile.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/gio/gfile.c b/gio/gfile.c index 65083efb7..22f74230c 100644 --- a/gio/gfile.c +++ b/gio/gfile.c @@ -3757,6 +3757,11 @@ g_file_make_directory_with_parents (GFile *file, if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; + /* Try for the simple case of not having to create any parent + * directories. If any parent directory needs to be created, this + * call will fail with NOT_FOUND. If that happens, then that value of + * my_error persists into the while loop below. + */ g_file_make_directory (file, cancellable, &my_error); if (!g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { @@ -3767,6 +3772,13 @@ g_file_make_directory_with_parents (GFile *file, work_file = g_object_ref (file); + /* Creates the parent directories as needed. In case any particular + * creation operation fails for lack of other parent directories + * (NOT_FOUND), the directory is added to a list of directories to + * create later, and the value of my_error is retained until the next + * iteration of the loop. After the loop my_error should either be + * empty or contain a real failure condition. + */ while (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { GFile *parent_file; @@ -3792,6 +3804,11 @@ g_file_make_directory_with_parents (GFile *file, g_object_unref (parent_file); } + /* All directories should be able to be created now, so an error at + * this point means the whole operation must fail -- except an EXISTS + * error, which means that another process already created the + * directory in between the previous failure and now. + */ for (l = list; my_error == NULL && l; l = l->next) { g_file_make_directory ((GFile *) l->data, cancellable, &my_error); @@ -3809,6 +3826,10 @@ g_file_make_directory_with_parents (GFile *file, list = g_list_remove (list, list->data); } + /* At this point an error in my_error means a that something + * unexpected failed in either of the loops above, so the whole + * operation must fail. + */ if (my_error != NULL) { g_propagate_error (error, my_error);