]> git.localhorst.tv Git - blank.git/commitdiff
file and directory removal functions
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 14 Nov 2016 16:08:27 +0000 (17:08 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 14 Nov 2016 16:08:27 +0000 (17:08 +0100)
src/io/filesystem.cpp
src/io/filesystem.hpp

index 1fd94a0ae152a4313bc61d707ad012fc4f942c1a..b0a9126fc5192be77dde7813abaebad3e6e32e82 100644 (file)
@@ -1,8 +1,15 @@
 #include "filesystem.hpp"
 
 #include <cerrno>
+#include <cstdio>
+#include <cstring>
 #ifdef _WIN32
+#  include <conio.h>
 #  include <direct.h>
+#  include <windows.h>
+#else
+#  include <dirent.h>
+#  include <sys/types.h>
 #endif
 #include <sys/stat.h>
 
@@ -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
+}
+
 }
index b69352a4ba962a4292031ef1662fd5a2274561f4..2af55fcce265d866ef33139a470fb0555fc28cd3 100644 (file)
@@ -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