[PATCH] Improve gnome_vfs_xfer_delete_items_common() error handling



The attached patch makes the deletion code handle errors during file
info fetching.

The progress phase is quite fragile, even after this patch has been
applied :(.

The deletion helper is used for deletion operations, and for cleanup
during a merged copy (i.e. a move operation that conflicted, or a move
between different FS). It sounds like a bad idea to hop forth and back
between the progress phases (i.e. CLEANUP -> DELETESOURCE (error
handling) -> CLEANUP (normal progress) -> ...), but essentially we'll
see an unannounced CLEANUP->DELETESOURCE hop (in the call_often in
remove_directory/file) when called in CLEANUP mode, since we don't never
do a call_progress.

I am also aware that for multiple URIs in the CLEANUP case, we'll never
get a CLEANUP status again, so thephase seen by the error handler
depends on whether we're eating the first URI or subsequent ones.

I have no clue how we should handle this (the current phase bit just
doesn't seem to be appropriate), but the most important thing seems to
be to make users aware of any file operation failure, especially in the
VFAT case, not the details of the progress info (aside from the URIs).

-- 
Christian Neumair <chris gnome-de org>
Index: libgnomevfs/gnome-vfs-xfer.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-xfer.c,v
retrieving revision 1.141
diff -u -p -r1.141 gnome-vfs-xfer.c
--- libgnomevfs/gnome-vfs-xfer.c	6 Nov 2006 12:38:12 -0000	1.141
+++ libgnomevfs/gnome-vfs-xfer.c	26 Dec 2006 20:36:49 -0000
@@ -2173,35 +2174,49 @@ gnome_vfs_xfer_delete_items_common (cons
 	GnomeVFSResult result;
 	GnomeVFSURI *uri;
 	const GList *p;
+	gboolean retry;
 	gboolean skip;
 
 	result = GNOME_VFS_OK;
 	
 	for (p = source_uri_list;  p != NULL; p = p->next) {
-	
 		skip = FALSE;
 		/* get the URI and VFSFileInfo for each */
 		uri = p->data;
 
+		progress_set_source_target_uris (progress, uri, NULL);
+
 		info = gnome_vfs_file_info_new ();
-		result = gnome_vfs_get_file_info_uri (uri, info, 
-						      GNOME_VFS_FILE_INFO_DEFAULT);
 
-		if (result != GNOME_VFS_OK) {
-			gnome_vfs_file_info_unref (info);
-			break;
-		}
+		do {
+			retry = FALSE;
 
-		progress_set_source_target_uris (progress, uri, NULL);
-		if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) {
-			result = remove_directory (uri, TRUE, progress, xfer_options, 
-						   &error_mode, &skip);
-		} else {
-			result = remove_file (uri, progress, xfer_options, &error_mode,
-					      &skip);
+			gnome_vfs_file_info_clear (info);
+			result = gnome_vfs_get_file_info_uri (uri, info, 
+							      GNOME_VFS_FILE_INFO_DEFAULT);
+
+			if (result != GNOME_VFS_OK) {
+				/* handle the error case */
+				retry = handle_error (&result, progress,
+						      &error_mode, &skip);
+			}
+		} while (retry);
+
+		if (result == GNOME_VFS_OK && !skip) {
+			if (info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) {
+				result = remove_directory (uri, TRUE, progress, xfer_options, 
+							   &error_mode, &skip);
+			} else {
+				result = remove_file (uri, progress, xfer_options, &error_mode,
+						      &skip);
+			}
 		}
 
 		gnome_vfs_file_info_unref (info);
+
+		if (result != GNOME_VFS_OK && !skip) {
+			break;
+		}
 	}
 
 	return result;
@@ -2233,6 +2248,8 @@ gnome_vfs_xfer_delete_items (const GList
 	progress->progress_info->top_level_item = TRUE;
 	if (result != GNOME_VFS_ERROR_INTERRUPTED) {
 		call_progress (progress, GNOME_VFS_XFER_PHASE_READYTOGO);
+
+		progress->progress_info->phase = GNOME_VFS_XFER_PHASE_DELETESOURCE;
 		result = gnome_vfs_xfer_delete_items_common (source_uri_list,
 			error_mode, xfer_options, progress);
 	}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]