aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2012-03-26 00:21:38 +0300
committerPerttu Ahola <celeron55@gmail.com>2012-03-26 08:36:59 +0300
commit5b31d32da8b1dc8b5e60b495bdfc20a563487cc7 (patch)
tree5287415aa1e80d443932bda29d1d67312592a0a5
parentdcef5183f7c2a12f7bd4990bc9a3fe9d27bef55b (diff)
downloadminetest-5b31d32da8b1dc8b5e60b495bdfc20a563487cc7.tar.gz
minetest-5b31d32da8b1dc8b5e60b495bdfc20a563487cc7.tar.bz2
minetest-5b31d32da8b1dc8b5e60b495bdfc20a563487cc7.zip
Better file/directory removal platform code and utilities
-rw-r--r--src/filesys.cpp134
-rw-r--r--src/filesys.h19
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