Better file/directory removal platform code and utilities
parent
dcef5183f7
commit
5b31d32da8
134
src/filesys.cpp
134
src/filesys.cpp
|
@ -138,32 +138,75 @@ bool PathExists(std::string path)
|
||||||
return (GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES);
|
return (GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsDir(std::string path)
|
||||||
|
{
|
||||||
|
DWORD attr = GetFileAttributes(path.c_str());
|
||||||
|
return (attr != INVALID_FILE_ATTRIBUTES &&
|
||||||
|
(attr & FILE_ATTRIBUTE_DIRECTORY));
|
||||||
|
}
|
||||||
|
|
||||||
bool RecursiveDelete(std::string path)
|
bool RecursiveDelete(std::string path)
|
||||||
{
|
{
|
||||||
infostream<<"Removing \""<<path<<"\""<<std::endl;
|
infostream<<"Recursively deleting \""<<path<<"\""<<std::endl;
|
||||||
|
|
||||||
//return false;
|
DWORD attr = GetFileAttributes(path.c_str());
|
||||||
|
bool is_directory = (attr != INVALID_FILE_ATTRIBUTES &&
|
||||||
// This silly function needs a double-null terminated string...
|
(attr & FILE_ATTRIBUTE_DIRECTORY));
|
||||||
// Well, we'll just make sure it has at least two, then.
|
if(!is_directory)
|
||||||
path += "\0\0";
|
{
|
||||||
|
infostream<<"RecursiveDelete: Deleting file "<<path<<std::endl;
|
||||||
SHFILEOPSTRUCT sfo;
|
//bool did = DeleteFile(path.c_str());
|
||||||
sfo.hwnd = NULL;
|
bool did = true;
|
||||||
sfo.wFunc = FO_DELETE;
|
if(!did){
|
||||||
sfo.pFrom = path.c_str();
|
errorstream<<"RecursiveDelete: Failed to delete file "
|
||||||
sfo.pTo = NULL;
|
<<path<<std::endl;
|
||||||
sfo.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR;
|
return false;
|
||||||
|
}
|
||||||
int r = SHFileOperation(&sfo);
|
}
|
||||||
|
else
|
||||||
if(r != 0)
|
{
|
||||||
errorstream<<"SHFileOperation returned "<<r<<std::endl;
|
infostream<<"RecursiveDelete: Deleting content of directory "
|
||||||
|
<<path<<std::endl;
|
||||||
//return (r == 0);
|
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;
|
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
|
#else // POSIX
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -249,6 +292,14 @@ bool PathExists(std::string path)
|
||||||
return (stat(path.c_str(),&st) == 0);
|
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)
|
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
|
#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)
|
bool RecursiveDeleteContent(std::string path)
|
||||||
{
|
{
|
||||||
infostream<<"Removing content of \""<<path<<"\""<<std::endl;
|
infostream<<"Removing content of \""<<path<<"\""<<std::endl;
|
||||||
|
|
|
@ -40,24 +40,35 @@ struct DirListNode
|
||||||
std::string name;
|
std::string name;
|
||||||
bool dir;
|
bool dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<DirListNode> GetDirListing(std::string path);
|
std::vector<DirListNode> GetDirListing(std::string path);
|
||||||
|
|
||||||
// Returns true if already exists
|
// Returns true if already exists
|
||||||
bool CreateDir(std::string path);
|
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 PathExists(std::string path);
|
||||||
|
|
||||||
|
bool IsDir(std::string path);
|
||||||
|
|
||||||
// Only pass full paths to this one. True on success.
|
// Only pass full paths to this one. True on success.
|
||||||
// NOTE: The WIN32 version returns always true.
|
// NOTE: The WIN32 version returns always true.
|
||||||
bool RecursiveDelete(std::string path);
|
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.
|
// Only pass full paths to this one. True on success.
|
||||||
bool RecursiveDeleteContent(std::string path);
|
bool RecursiveDeleteContent(std::string path);
|
||||||
|
|
||||||
|
// Create all directories on the given path that don't already exist.
|
||||||
|
bool CreateAllDirs(std::string path);
|
||||||
|
|
||||||
}//fs
|
}//fs
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue