diff --git a/Applications/FileManager/FileUtils.cpp b/Applications/FileManager/FileUtils.cpp index f36ae11fd6..003826b479 100644 --- a/Applications/FileManager/FileUtils.cpp +++ b/Applications/FileManager/FileUtils.cpp @@ -9,6 +9,42 @@ namespace FileUtils { +int delete_directory(String directory, String& file_that_caused_error) +{ + CDirIterator iterator(directory, CDirIterator::SkipDots); + if (iterator.has_error()) { + file_that_caused_error = directory; + return -1; + } + + while (iterator.has_next()) { + auto file_to_delete = String::format("%s/%s", directory.characters(), iterator.next_path().characters()); + struct stat st; + + if (lstat(file_to_delete.characters(), &st)) { + file_that_caused_error = file_to_delete; + return errno; + } + + if (S_ISDIR(st.st_mode)) { + if (delete_directory(file_to_delete, file_to_delete)) { + file_that_caused_error = file_to_delete; + return errno; + } + } else if (unlink(file_to_delete.characters())) { + file_that_caused_error = file_to_delete; + return errno; + } + } + + if (rmdir(directory.characters())) { + file_that_caused_error = directory; + return errno; + } + + return 0; +} + bool copy_file_or_directory(const String& src_path, const String& dst_path) { int duplicate_count = 0; diff --git a/Applications/FileManager/FileUtils.h b/Applications/FileManager/FileUtils.h index 6f58cf61cb..9fcacaf10e 100644 --- a/Applications/FileManager/FileUtils.h +++ b/Applications/FileManager/FileUtils.h @@ -2,9 +2,11 @@ #include namespace FileUtils { -bool copy_file_or_directory(const String& src_path, const String& dst_path); +int delete_directory(String directory, String& file_that_caused_error); +bool copy_file_or_directory(const String& src_path, const String& dst_path); String get_duplicate_name(const String& path, int duplicate_count); bool copy_file(const String& src_path, const String& dst_path, const struct stat& src_stat, int src_fd); bool copy_directory(const String& src_path, const String& dst_path); -} \ No newline at end of file + +} diff --git a/Applications/FileManager/main.cpp b/Applications/FileManager/main.cpp index 2fb5a9e12a..6f3155b72f 100644 --- a/Applications/FileManager/main.cpp +++ b/Applications/FileManager/main.cpp @@ -252,8 +252,33 @@ int main(int argc, char** argv) return; } } + for (auto& path : paths) { - if (unlink(path.characters()) < 0) { + struct stat st; + if (lstat(path.characters(), &st)) { + GMessageBox::show( + String::format("lstat(%s) failed: %s", path.characters(), strerror(errno)), + "Delete failed", + GMessageBox::Type::Error, + GMessageBox::InputType::OK, + window); + break; + } + + if (S_ISDIR(st.st_mode)) { + String error_path; + int error = FileUtils::delete_directory(path, error_path); + + if (error) { + GMessageBox::show( + String::format("Failed to delete directory \"%s\": %s", error_path.characters(), strerror(error)), + "Delete failed", + GMessageBox::Type::Error, + GMessageBox::InputType::OK, + window); + break; + } + } else if (unlink(path.characters()) < 0) { int saved_errno = errno; GMessageBox::show( String::format("unlink(%s) failed: %s", path.characters(), strerror(saved_errno)),