From 3767297f8a338bafbc3e621877fb6ba8435680bb Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Mon, 14 Nov 2016 17:08:27 +0100 Subject: [PATCH] file and directory removal functions --- src/io/filesystem.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++ src/io/filesystem.hpp | 8 +++++ 2 files changed, 92 insertions(+) diff --git a/src/io/filesystem.cpp b/src/io/filesystem.cpp index 1fd94a0..b0a9126 100644 --- a/src/io/filesystem.cpp +++ b/src/io/filesystem.cpp @@ -1,8 +1,15 @@ #include "filesystem.hpp" #include +#include +#include #ifdef _WIN32 +# include # include +# include +#else +# include +# include #endif #include @@ -124,4 +131,81 @@ bool make_dirs(const std::string &path) { } } + +bool remove_file(const std::string &path) { + return remove(path.c_str()) == 0; +} + + +bool remove_dir(const std::string &path) { +#ifdef _WIN32 + + // shamelessly stolen from http://www.codeguru.com/forum/showthread.php?t=239271 + const std::string pattern = path + "\\*.*"; + WIN32_FIND_DATA info; + HANDLE file = FindFirstFile(pattern.c_str(), &info); + if (file == INVALID_HANDLE_VALUE) { + // already non-existing + return true; + } + + do { + if ( + strncmp(info.cFileName, ".", 2) == 0 || + strncmp(info.cFileName, "..", 3) == 0 + ) { + continue; + } + const std::string sub_path = path + '\\' + info.cFileName; + if ((info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { + if (!remove_dir(sub_path)) { + return false; + } + } else { + if (!SetFileAttributes(sub_path.c_str(), FILE_ATTRIBUTE_NORMAL)) { + return false; + } + if (!remove_file(sub_path)) { + return false; + } + } + } while (FindNextFile(file, &info)); + FindClose(file); + + DWORD error = GetLastError(); + if (error != ERROR_NO_MORE_FILES) { + return false; + } + // is this (NORMAL vs DIRECTORY) really correct? + if (!SetFileAttributes(path.c_str(), FILE_ATTRIBUTE_NORMAL)) { + return false; + } + return RemoveDirectory(path.c_str()); + +#else + + DIR *dir = opendir(path.c_str()); + for (dirent *entry = readdir(dir); entry != nullptr; entry = readdir(dir)) { + if ( + strncmp(entry->d_name, ".", 2) == 0 || + strncmp(entry->d_name, "..", 3) == 0 + ) { + continue; + } + const std::string sub_path = path + '/' + entry->d_name; + if (is_dir(sub_path)) { + if (!remove_dir(sub_path)) { + return false; + } + } else { + if (!remove_file(sub_path)) { + return false; + } + } + } + return remove(path.c_str()) == 0; + +#endif +} + } diff --git a/src/io/filesystem.hpp b/src/io/filesystem.hpp index b69352a..2af55fc 100644 --- a/src/io/filesystem.hpp +++ b/src/io/filesystem.hpp @@ -34,6 +34,14 @@ inline bool make_dir(const std::string &s) { /// @return true if the directory was created or already exists bool make_dirs(const std::string &); +/// remove given file +/// @return true on success +bool remove_file(const std::string &); +/// recursively remove given directory +/// may leave the directory partially removed on failure +/// @return true if the directory was completely removed +bool remove_dir(const std::string &); + } #endif -- 2.39.2