From 4bdcee2b9d9bd424d6b3ba1019ee107c0dfc3781 Mon Sep 17 00:00:00 2001 From: Iskustvo Date: Wed, 14 Feb 2018 00:04:11 +0100 Subject: [PATCH] [X11] Improving error detection in move_to_trash (cherry picked from commit 268d7c7c5b4249c0281cbb7f7fc8a66b2ebdc969) --- drivers/unix/dir_access_unix.cpp | 1 + platform/x11/os_x11.cpp | 55 +++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index 4a467293fde..39444315164 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -361,6 +361,7 @@ Error DirAccessUnix::rename(String p_path, String p_new_path) { return ::rename(p_path.utf8().get_data(), p_new_path.utf8().get_data()) == 0 ? OK : FAILED; } + Error DirAccessUnix::remove(String p_path) { if (p_path.is_rel_path()) diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index bd2abc10945..6561131e80c 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -32,6 +32,7 @@ #include "drivers/gles3/rasterizer_gles3.h" #include "errno.h" #include "key_mapping_x11.h" +#include "os/dir_access.h" #include "print_string.h" #include "servers/visual/visual_server_raster.h" #include "servers/visual/visual_server_wrap_mt.h" @@ -2519,48 +2520,66 @@ static String get_mountpoint(const String &p_path) { } Error OS_X11::move_to_trash(const String &p_path) { - String trashcan = ""; + String trash_can = ""; String mnt = get_mountpoint(p_path); + // If there is a directory "[Mountpoint]/.Trash-[UID]/files", use it as the trash can. if (mnt != "") { String path(mnt + "/.Trash-" + itos(getuid()) + "/files"); struct stat s; if (!stat(path.utf8().get_data(), &s)) { - trashcan = path; + trash_can = path; } } - if (trashcan == "") { + // Otherwise, if ${XDG_DATA_HOME} is defined, use "${XDG_DATA_HOME}/Trash/files" as the trash can. + if (trash_can == "") { char *dhome = getenv("XDG_DATA_HOME"); if (dhome) { - trashcan = String(dhome) + "/Trash/files"; + trash_can = String(dhome) + "/Trash/files"; } } - if (trashcan == "") { + // Otherwise, if ${HOME} is defined, use "${HOME}/.local/share/Trash/files" as the trash can. + if (trash_can == "") { char *home = getenv("HOME"); if (home) { - trashcan = String(home) + "/.local/share/Trash/files"; + trash_can = String(home) + "/.local/share/Trash/files"; } } - if (trashcan == "") { - ERR_PRINTS("move_to_trash: Could not determine trashcan location"); + // Issue an error if none of the previous locations is appropriate for the trash can. + if (trash_can == "") { + ERR_PRINTS("move_to_trash: Could not determine the trash can location"); return FAILED; } - List args; - args.push_back("-p"); - args.push_back(trashcan); - Error err = execute("mkdir", args, true); - if (err == OK) { - List args2; - args2.push_back(p_path); - args2.push_back(trashcan); - err = execute("mv", args2, true); + // Create needed directories for decided trash can location. + DirAccess *dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + Error err = dir_access->make_dir_recursive(trash_can); + memdelete(dir_access); + + // Issue an error if trash can is not created proprely. + if (err != OK) { + ERR_PRINTS("move_to_trash: Could not create the trash can \"" + trash_can + "\""); + return err; } - return err; + // The trash can is successfully created, now move the given resource to it. + // Do not use DirAccess:rename() because it can't move files across multiple mountpoints. + List mv_args; + mv_args.push_back(p_path); + mv_args.push_back(trash_can); + int retval; + err = execute("mv", mv_args, true, NULL, NULL, &retval); + + // Issue an error if "mv" failed to move the given resource to the trash can. + if (err != OK || retval != 0) { + ERR_PRINTS("move_to_trash: Could not move the resource \"" + p_path + "\" to the trash can \"" + trash_can + "\""); + return FAILED; + } + + return OK; } OS::LatinKeyboardVariant OS_X11::get_latin_keyboard_variant() const {