diff options
author | Perttu Ahola <celeron55@gmail.com> | 2012-03-26 00:21:38 +0300 |
---|---|---|
committer | Perttu Ahola <celeron55@gmail.com> | 2012-03-26 08:36:59 +0300 |
commit | 5b31d32da8b1dc8b5e60b495bdfc20a563487cc7 (patch) | |
tree | 5287415aa1e80d443932bda29d1d67312592a0a5 | |
parent | dcef5183f7c2a12f7bd4990bc9a3fe9d27bef55b (diff) | |
download | minetest-5b31d32da8b1dc8b5e60b495bdfc20a563487cc7.tar.gz minetest-5b31d32da8b1dc8b5e60b495bdfc20a563487cc7.tar.bz2 minetest-5b31d32da8b1dc8b5e60b495bdfc20a563487cc7.zip |
Better file/directory removal platform code and utilities
-rw-r--r-- | src/filesys.cpp | 134 | ||||
-rw-r--r-- | src/filesys.h | 19 |
2 files changed, 129 insertions, 24 deletions
diff --git a/src/filesys.cpp b/src/filesys.cpp index e8a9e88db..ab950d464 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -138,32 +138,75 @@ bool PathExists(std::string path) return (GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES); } -bool RecursiveDelete(std::string path) +bool IsDir(std::string path) { - infostream<<"Removing \""<<path<<"\""<<std::endl; - - //return false; - - // This silly function needs a double-null terminated string... - // Well, we'll just make sure it has at least two, then. - path += "\0\0"; - - SHFILEOPSTRUCT sfo; - sfo.hwnd = NULL; - sfo.wFunc = FO_DELETE; - sfo.pFrom = path.c_str(); - sfo.pTo = NULL; - sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR; - - int r = SHFileOperation(&sfo); + DWORD attr = GetFileAttributes(path.c_str()); + return (attr != INVALID_FILE_ATTRIBUTES && + (attr & FILE_ATTRIBUTE_DIRECTORY)); +} - if(r != 0) - errorstream<<"SHFileOperation returned "<<r<<std::endl; +bool RecursiveDelete(std::string path) +{ + infostream<<"Recursively deleting \""<<path<<"\""<<std::endl; - //return (r == 0); + DWORD attr = GetFileAttributes(path.c_str()); + bool is_directory = (attr != INVALID_FILE_ATTRIBUTES && + (attr & FILE_ATTRIBUTE_DIRECTORY)); + if(!is_directory) + { + infostream<<"RecursiveDelete: Deleting file "<<path<<std::endl; + //bool did = DeleteFile(path.c_str()); + bool did = true; + if(!did){ + errorstream<<"RecursiveDelete: Failed to delete file " + <<path<<std::endl; + return false; + } + } + else + { + infostream<<"RecursiveDelete: Deleting content of directory " + <<path<<std::endl; + std::vector<DirListNode> content = GetDirListing(path); + for(int i=0; i<content.size(); i++){ + const DirListNode &n = content[i]; + std::string fullpath = path + DIR_DELIM + n.name; + bool did = RecursiveDelete(fullpath); + if(!did){ + errorstream<<"RecursiveDelete: Failed to recurse to " + <<fullpath<<std::endl; + return false; + } + } + infostream<<"RecursiveDelete: Deleting directory "<<path<<std::endl; + //bool did = RemoveDirectory(path.c_str(); + bool did = true; + if(!did){ + errorstream<<"Failed to recursively delete directory " + <<path<<std::endl; + return false; + } + } return true; } +bool DeleteSingleFileOrEmptyDirectory(std::string path) +{ + DWORD attr = GetFileAttributes(path.c_str()); + bool is_directory = (attr != INVALID_FILE_ATTRIBUTES && + (attr & FILE_ATTRIBUTE_DIRECTORY)); + if(!is_directory) + { + bool did = DeleteFile(path.c_str()); + return did; + } + else + { + bool did = RemoveDirectory(path.c_str()); + return did; + } +} + #else // POSIX #include <sys/types.h> @@ -249,6 +292,14 @@ bool PathExists(std::string path) return (stat(path.c_str(),&st) == 0); } +bool IsDir(std::string path) +{ + struct stat statbuf; + if(stat(path.c_str(), &statbuf)) + return false; // Actually error; but certainly not a directory + return ((statbuf.st_mode & S_IFDIR) == S_IFDIR); +} + bool RecursiveDelete(std::string path) { /* @@ -295,8 +346,51 @@ bool RecursiveDelete(std::string path) } } +bool DeleteSingleFileOrEmptyDirectory(std::string path) +{ + if(IsDir(path)){ + bool did = (rmdir(path.c_str()) == 0); + if(!did) + errorstream<<"rmdir errno: "<<errno<<": "<<strerror(errno) + <<std::endl; + return did; + } else { + bool did = (unlink(path.c_str()) == 0); + if(!did) + errorstream<<"unlink errno: "<<errno<<": "<<strerror(errno) + <<std::endl; + return did; + } +} + #endif +void GetRecursiveSubPaths(std::string path, std::vector<std::string> &dst) +{ + std::vector<DirListNode> content = GetDirListing(path); + for(unsigned int i=0; i<content.size(); i++){ + const DirListNode &n = content[i]; + std::string fullpath = path + DIR_DELIM + n.name; + dst.push_back(fullpath); + GetRecursiveSubPaths(fullpath, dst); + } +} + +bool DeletePaths(const std::vector<std::string> &paths) +{ + bool success = true; + // Go backwards to succesfully delete the output of GetRecursiveSubPaths + for(int i=paths.size()-1; i>=0; i--){ + const std::string &path = paths[i]; + bool did = DeleteSingleFileOrEmptyDirectory(path); + if(!did){ + errorstream<<"Failed to delete "<<path<<std::endl; + success = false; + } + } + return success; +} + bool RecursiveDeleteContent(std::string path) { infostream<<"Removing content of \""<<path<<"\""<<std::endl; diff --git a/src/filesys.h b/src/filesys.h index 8bf43c3fa..07c18e446 100644 --- a/src/filesys.h +++ b/src/filesys.h @@ -40,24 +40,35 @@ struct DirListNode std::string name; bool dir; }; - std::vector<DirListNode> GetDirListing(std::string path); // Returns true if already exists bool CreateDir(std::string path); -// Create all directories on the given path that don't already exist. -bool CreateAllDirs(std::string path); - bool PathExists(std::string path); +bool IsDir(std::string path); + // Only pass full paths to this one. True on success. // NOTE: The WIN32 version returns always true. bool RecursiveDelete(std::string path); +bool DeleteSingleFileOrEmptyDirectory(std::string path); + +/* Multiplatform */ + +// The path itself not included +void GetRecursiveSubPaths(std::string path, std::vector<std::string> &dst); + +// Tries to delete all, returns false if any failed +bool DeletePaths(const std::vector<std::string> &paths); + // Only pass full paths to this one. True on success. bool RecursiveDeleteContent(std::string path); +// Create all directories on the given path that don't already exist. +bool CreateAllDirs(std::string path); + }//fs #endif |