[gnome-commander] Don't use g_file_measure_disk_usage() before calling g_file_delete, finally fixing #59
- From: Uwe Scholz <uwescholz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-commander] Don't use g_file_measure_disk_usage() before calling g_file_delete, finally fixing #59
- Date: Tue, 23 Nov 2021 20:15:07 +0000 (UTC)
commit 7ea6bdcfb07cfc172b24c64a3b0d489627a06e28
Author: Uwe Scholz <u scholz83 gmx de>
Date: Tue Nov 23 20:47:02 2021 +0100
Don't use g_file_measure_disk_usage() before calling g_file_delete, finally fixing #59
This is needed when working with remote directorys. Instead, we are just trying
to delete the file/directory. If it is a non-empty directory, the error type
G_IO_ERROR_NOT_EMPTY is received, after which we can step into the non-empty
directory and recursively delete everything there.
Furthermore, I cleaned up the code a bit by splitting up the original function.
NEWS | 1 +
doc/C/releases.xml | 3 +
src/dialogs/gnome-cmd-delete-dialog.cc | 195 +++++++++++++++++----------------
3 files changed, 104 insertions(+), 95 deletions(-)
---
diff --git a/NEWS b/NEWS
index 15eb5fee..f9047003 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,7 @@ Bug fixes:
* Fixed issue #47 (Duplicate directory when copying over an existing directory)
* Fixed issue #51 (Move and not copy by default on same filesystem)
* Fixed issue #52 (Auto refresh when changing permissions etc)
+ * Fixed issue #59 (On ssh connection, to delete a renamed folder/file don't work)
* Fixed issue #74 (Does not show mounted external drives)
* Fixed issue #75 (Newly inserted DVD does not show up)
diff --git a/doc/C/releases.xml b/doc/C/releases.xml
index 4a20045e..fd6fc74b 100644
--- a/doc/C/releases.xml
+++ b/doc/C/releases.xml
@@ -62,6 +62,9 @@
<listitem>
<para>Fixed issue #52 (Auto refresh when changing permissions etc)</para>
</listitem>
+ <listitem>
+ <para>Fixed issue #59 (On ssh connection, to delete a renamed folder/file don't
work)</para>
+ </listitem>
<listitem>
<para>Fixed issue #74 (Does not show mounted external drives)</para>
</listitem>
diff --git a/src/dialogs/gnome-cmd-delete-dialog.cc b/src/dialogs/gnome-cmd-delete-dialog.cc
index 905fa5b0..ef412c12 100644
--- a/src/dialogs/gnome-cmd-delete-dialog.cc
+++ b/src/dialogs/gnome-cmd-delete-dialog.cc
@@ -40,6 +40,8 @@ using namespace std;
#define DELETE_ERROR_ACTION_RETRY 1
#define DELETE_ERROR_ACTION_SKIP 2
+static gboolean perform_delete_operation_r(DeleteData *deleteData, GList *gnomeCmdFileGList);
+
inline void cleanup (DeleteData *deleteData)
{
gnome_cmd_file_list_free (deleteData->gnomeCmdFiles);
@@ -134,12 +136,59 @@ inline void create_delete_progress_win (DeleteData *deleteData)
gtk_widget_show (deleteData->progwin);
}
+
+/**
+ * @brief This function is meant to be called from within the function perform_delete_operation_r().
+ * It will dive through a non-empty directory and tries to recursively delete all files and
+ * folders inside of it.
+ *
+ * @param gnomeCmdDir Directory to go through and which should be deleted
+ * @param deleteData DeleteData object
+ * @return TRUE if deletion was performed successfully
+ */
+static gboolean perform_delete_subdir(GnomeCmdDir *gnomeCmdDir, DeleteData *deleteData)
+{
+ gboolean deleted = TRUE;
+ for (GList *dirChildItem = gnome_cmd_dir_get_files (gnomeCmdDir); dirChildItem; dirChildItem =
dirChildItem->next)
+ {
+ // 'deleted' can be set below within this for-loop
+ if (!deleted && deleteData->problem_action == DELETE_ERROR_ACTION_ABORT)
+ {
+ gnome_cmd_dir_unref (gnomeCmdDir);
+ return FALSE;
+ }
+ if (!deleted && deleteData->problem_action == DELETE_ERROR_ACTION_RETRY)
+ {
+ dirChildItem = dirChildItem->prev ? dirChildItem->prev : dirChildItem;
+ deleteData->problem_action = -1;
+ }
+ if (!deleted && deleteData->problem_action == DELETE_ERROR_ACTION_SKIP)
+ {
+ // just go on and set problem_action to the default value
+ deleteData->problem_action = -1;
+ }
+
+ auto gnomeCmdFile = static_cast<GnomeCmdFile*>(dirChildItem->data);
+
+ if (gnomeCmdFile->is_dotdot)
+ continue;
+
+ GList *childsList = nullptr;
+ childsList = g_list_append(childsList, gnomeCmdFile);
+ deleted = perform_delete_operation_r (deleteData, childsList);
+ g_list_free(childsList);
+ }
+ return deleted;
+}
+
/**
* This function recursively removes files of a given GnomeCmdFile list and stores
* possible errors or the progress information in the deleteData object.
*/
static gboolean perform_delete_operation_r(DeleteData *deleteData, GList *gnomeCmdFileGList)
{
+ GError *tmpError = nullptr;
+
for (GList *gCmdFileGListItem = gnomeCmdFileGList; gCmdFileGListItem; gCmdFileGListItem =
gCmdFileGListItem->next)
{
if (deleteData->stop)
@@ -147,112 +196,47 @@ static gboolean perform_delete_operation_r(DeleteData *deleteData, GList *gnomeC
return FALSE;
}
- auto gnomeCmdFile = (GnomeCmdFile *) gCmdFileGListItem->data;
+ auto gnomeCmdFile = static_cast<GnomeCmdFile*>(gCmdFileGListItem->data);
g_return_val_if_fail (GNOME_CMD_IS_FILE(gnomeCmdFile), FALSE);
g_return_val_if_fail (G_IS_FILE_INFO(gnomeCmdFile->gFileInfo), FALSE);
- auto filenameTmp = g_file_info_get_display_name(gnomeCmdFile->gFileInfo);
+ auto filenameTmp = gnomeCmdFile->get_name();
if (gnomeCmdFile->is_dotdot || strcmp(filenameTmp, ".") == 0)
continue;
- GError *tmpError = nullptr;
- auto gFile = gnomeCmdFile->gFile;
-
- guint64 numFiles = 0;
- guint64 numDirs = 0;
+ g_file_delete (gnomeCmdFile->gFile, nullptr, &tmpError);
- if (!g_file_measure_disk_usage (gFile,
- G_FILE_MEASURE_NONE,
- nullptr, nullptr, nullptr, nullptr,
- &numDirs,
- &numFiles,
- &tmpError))
+ if (tmpError && g_error_matches (tmpError, G_IO_ERROR, G_IO_ERROR_NOT_EMPTY))
{
- g_warning ("Failed to measure disk usage of %s: %s", g_file_peek_path (gFile),
tmpError->message);
- g_propagate_error (&(deleteData->error), tmpError);
- deleteData->problemFileName = g_file_peek_path(gFile);
- delete_progress_update(deleteData);
+ auto gnomeCmdDir = GNOME_CMD_DIR (gnomeCmdFile);
+ gnome_cmd_dir_list_files (gnomeCmdDir, FALSE);
+
+ if (!perform_delete_subdir(gnomeCmdDir, deleteData))
return FALSE;
- }
- if ((numDirs == 1 && numFiles == 0) // Empty directory
- || (get_gfile_attribute_boolean(gFile, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK)) //We want delete
symlinks!
- || (get_gfile_attribute_uint32(gFile, G_FILE_ATTRIBUTE_STANDARD_TYPE) != G_FILE_TYPE_DIRECTORY))
// Not a directory
- {
- // DELETE IT!
- if (!g_file_delete (gFile, nullptr, &tmpError) &&
- !g_error_matches (tmpError, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
- {
- g_warning ("Failed to delete %s: %s", g_file_peek_path (gFile), tmpError->message);
- g_propagate_error (&(deleteData->error), tmpError);
- deleteData->problemFileName = g_file_peek_path(gFile);
- delete_progress_update(deleteData);
- if (deleteData->stop)
- return FALSE;
- }
- else
- {
- deleteData->deletedGnomeCmdFiles = g_list_append(deleteData->deletedGnomeCmdFiles,
gnomeCmdFile);
- deleteData->itemsDeleted++;
- delete_progress_update(deleteData);
- if (deleteData->stop)
- return FALSE;
- }
+ // Now remove the directory itself, as it is finally empty
+ GList *directory = nullptr;
+ directory = g_list_append(directory, gnomeCmdFile);
+ perform_delete_operation_r (deleteData, directory);
+ g_list_free(directory);
}
- else
+ else if (tmpError)
{
- gboolean deleted = TRUE;
- gboolean dirIsEmpty = TRUE;
-
- if (!GNOME_CMD_IS_DIR (gnomeCmdFile))
- return false;
-
- auto gnomeCmdDir = gnome_cmd_dir_ref (GNOME_CMD_DIR (gnomeCmdFile));
- gnome_cmd_dir_list_files (gnomeCmdDir, FALSE);
- for (GList *subFolderItem = gnome_cmd_dir_get_files (gnomeCmdDir); subFolderItem; subFolderItem
= subFolderItem->next)
- {
- // retValue can be set below within this for-loop
- if (!deleted && deleteData->problem_action == DELETE_ERROR_ACTION_ABORT)
- {
- gnome_cmd_dir_unref (gnomeCmdDir);
- return FALSE;
- }
- if (!deleted && deleteData->problem_action == DELETE_ERROR_ACTION_RETRY)
- {
- subFolderItem = subFolderItem->prev ? subFolderItem->prev : subFolderItem;
- deleteData->problem_action = -1;
- }
- if (!deleted && deleteData->problem_action == DELETE_ERROR_ACTION_SKIP)
- {
- // do nothing, just go on
- deleteData->problem_action = -1;
- dirIsEmpty = FALSE;
- }
-
- auto subGnomeCmdFile = (GnomeCmdFile *) subFolderItem->data;
-
- if (!subGnomeCmdFile->is_dotdot)
- {
- GList *subGnomeCmdFileList = nullptr;
-
- subGnomeCmdFileList = g_list_append(subGnomeCmdFileList, subGnomeCmdFile);
- deleted = perform_delete_operation_r (deleteData, subGnomeCmdFileList);
- g_list_free(subGnomeCmdFileList);
- }
- }
- gnome_cmd_dir_unref (gnomeCmdDir);
-
- if (dirIsEmpty)
- {
- // Now remove the directory itself, if it is finally empty
- GList *directory = nullptr;
- directory = g_list_append(directory, gnomeCmdFile);
- perform_delete_operation_r (deleteData, directory);
- g_list_free(directory);
- }
+ g_warning ("Failed to delete %s: %s", gnomeCmdFile->get_name(), tmpError->message);
+ g_propagate_error (&(deleteData->error), tmpError);
+ deleteData->problemFileName = gnomeCmdFile->get_name();
+ delete_progress_update(deleteData);
+ if (deleteData->stop)
+ return FALSE;
}
+
+ deleteData->deletedGnomeCmdFiles = g_list_append(deleteData->deletedGnomeCmdFiles, gnomeCmdFile);
+ deleteData->itemsDeleted++;
+ delete_progress_update(deleteData);
+ if (deleteData->stop)
+ return FALSE;
}
return TRUE;
}
@@ -341,13 +325,24 @@ void do_delete (DeleteData *deleteData, gboolean showProgress = true)
guint64 num_dirs = 0;
auto gFile = GNOME_CMD_FILE(fileListItem->data)->gFile;
g_return_if_fail(G_IS_FILE(gFile));
+ GError *error = nullptr;
g_file_measure_disk_usage (gFile,
G_FILE_MEASURE_NONE,
nullptr, nullptr, nullptr, nullptr,
&num_dirs,
&num_files,
- nullptr);
+ &error);
+
+ // If we cannot determine if gFile is empty or not, don't show progress dialog
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
+ {
+ showProgress = FALSE;
+ g_error_free (error);
+ error = nullptr;
+ break;
+ }
+
deleteData->itemsTotal += num_files + num_dirs;
}
@@ -386,6 +381,7 @@ static GList *remove_items_from_list_to_be_deleted(GList *files)
error = nullptr;
guint64 num_dirs;
guint64 num_files;
+ gboolean canNotMeasure = FALSE;
g_file_measure_disk_usage (gnomeCmdFile->gFile,
G_FILE_MEASURE_NONE,
@@ -393,7 +389,13 @@ static GList *remove_items_from_list_to_be_deleted(GList *files)
&num_dirs,
&num_files,
&error);
-
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
+ {
+ // If we cannot determine if gFile is empty or not, we have to assume it is not empty
+ canNotMeasure = TRUE;
+ g_error_free (error);
+ error = nullptr;
+ }
if (error)
{
g_message ("remove_items_from_list_to_be_deleted: g_file_measure_disk_usage failed: %s",
error->message);
@@ -406,11 +408,14 @@ static GList *remove_items_from_list_to_be_deleted(GList *files)
g_error_free (error);
return 0;
}
- if (num_dirs != 1 || num_files != 0) // num_dirs = 1 -> this is the folder to be deleted
+ if (num_dirs != 1 || num_files != 0 || canNotMeasure) // num_dirs = 1 -> this is the folder to
be deleted
{
gchar *msg = NULL;
- msg = g_strdup_printf (_("The directory “%s” is not empty. Do you really want to delete
it?"), gnomeCmdFile->get_name());
+ msg = canNotMeasure
+ ? g_strdup_printf (_("Do you really want to delete “%s”?"), gnomeCmdFile->get_name())
+ : g_strdup_printf (_("The directory “%s” is not empty. Do you really want to delete
it?"), gnomeCmdFile->get_name());
+
guiResponse = run_simple_dialog (*main_win, FALSE, GTK_MESSAGE_WARNING, msg, _("Delete"),
gnome_cmd_data.options.confirm_delete_default==GTK_BUTTONS_CANCEL ? 0 : 3,
_("Cancel"), _("Skip"),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]