mirror of
https://github.com/minetest/minetest.git
synced 2025-01-11 07:47:31 +01:00
Use execvp in fs::RecursiveDelete()
This commit is contained in:
parent
3f5a58a4e5
commit
c8f1efebea
@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <IFileArchive.h>
|
#include <IFileArchive.h>
|
||||||
#include <IFileSystem.h>
|
#include <IFileSystem.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
@ -43,6 +44,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#include <shlwapi.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <direct.h>
|
||||||
|
#else
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Error from last OS call as string
|
// Error from last OS call as string
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define LAST_OS_ERROR() porting::ConvertError(GetLastError())
|
#define LAST_OS_ERROR() porting::ConvertError(GetLastError())
|
||||||
@ -59,11 +73,6 @@ namespace fs
|
|||||||
* Windows *
|
* Windows *
|
||||||
***********/
|
***********/
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <shlwapi.h>
|
|
||||||
#include <io.h>
|
|
||||||
#include <direct.h>
|
|
||||||
|
|
||||||
std::vector<DirListNode> GetDirListing(const std::string &pathstring)
|
std::vector<DirListNode> GetDirListing(const std::string &pathstring)
|
||||||
{
|
{
|
||||||
std::vector<DirListNode> listing;
|
std::vector<DirListNode> listing;
|
||||||
@ -273,12 +282,6 @@ bool CopyFileContents(const std::string &source, const std::string &target)
|
|||||||
* POSIX *
|
* POSIX *
|
||||||
*********/
|
*********/
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
std::vector<DirListNode> GetDirListing(const std::string &pathstring)
|
std::vector<DirListNode> GetDirListing(const std::string &pathstring)
|
||||||
{
|
{
|
||||||
std::vector<DirListNode> listing;
|
std::vector<DirListNode> listing;
|
||||||
@ -383,39 +386,39 @@ bool RecursiveDelete(const std::string &path)
|
|||||||
|
|
||||||
infostream << "Removing \"" << path << "\"" << std::endl;
|
infostream << "Removing \"" << path << "\"" << std::endl;
|
||||||
|
|
||||||
pid_t child_pid = fork();
|
assert(IsPathAbsolute(path));
|
||||||
|
|
||||||
if(child_pid == 0)
|
const pid_t child_pid = fork();
|
||||||
{
|
|
||||||
|
if (child_pid == -1) {
|
||||||
|
errorstream << "fork errno: " << errno << ": " << strerror(errno)
|
||||||
|
<< std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child_pid == 0) {
|
||||||
// Child
|
// Child
|
||||||
const char *argv[4] = {
|
std::array<const char*, 4> argv = {
|
||||||
#ifdef __ANDROID__
|
"rm",
|
||||||
"/system/bin/rm",
|
|
||||||
#else
|
|
||||||
"/bin/rm",
|
|
||||||
#endif
|
|
||||||
"-rf",
|
"-rf",
|
||||||
path.c_str(),
|
path.c_str(),
|
||||||
NULL
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
verbosestream<<"Executing '"<<argv[0]<<"' '"<<argv[1]<<"' '"
|
execvp(argv[0], const_cast<char**>(argv.data()));
|
||||||
<<argv[2]<<"'"<<std::endl;
|
|
||||||
|
|
||||||
execv(argv[0], const_cast<char**>(argv));
|
// note: use cerr because our logging won't flush in forked process
|
||||||
|
std::cerr << "exec errno: " << errno << ": " << strerror(errno)
|
||||||
// Execv shouldn't return. Failed.
|
<< std::endl;
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Parent
|
// Parent
|
||||||
int child_status;
|
int status;
|
||||||
pid_t tpid;
|
pid_t tpid;
|
||||||
do{
|
do
|
||||||
tpid = wait(&child_status);
|
tpid = waitpid(child_pid, &status, 0);
|
||||||
}while(tpid != child_pid);
|
while (tpid != child_pid);
|
||||||
return (child_status == 0);
|
return WIFEXITED(status) && WEXITSTATUS(status) == 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ public:
|
|||||||
void testSafeWriteToFile();
|
void testSafeWriteToFile();
|
||||||
void testCopyFileContents();
|
void testCopyFileContents();
|
||||||
void testNonExist();
|
void testNonExist();
|
||||||
|
void testRecursiveDelete();
|
||||||
};
|
};
|
||||||
|
|
||||||
static TestFileSys g_test_instance;
|
static TestFileSys g_test_instance;
|
||||||
@ -56,6 +57,7 @@ void TestFileSys::runTests(IGameDef *gamedef)
|
|||||||
TEST(testSafeWriteToFile);
|
TEST(testSafeWriteToFile);
|
||||||
TEST(testCopyFileContents);
|
TEST(testCopyFileContents);
|
||||||
TEST(testNonExist);
|
TEST(testNonExist);
|
||||||
|
TEST(testRecursiveDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -338,3 +340,32 @@ void TestFileSys::testNonExist()
|
|||||||
auto ifs = open_ifstream(path.c_str(), false);
|
auto ifs = open_ifstream(path.c_str(), false);
|
||||||
UASSERT(!ifs.good());
|
UASSERT(!ifs.good());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestFileSys::testRecursiveDelete()
|
||||||
|
{
|
||||||
|
std::string dirs[2];
|
||||||
|
dirs[0] = getTestTempDirectory() + DIR_DELIM "a";
|
||||||
|
dirs[1] = dirs[0] + DIR_DELIM "b";
|
||||||
|
|
||||||
|
std::string files[2] = {
|
||||||
|
dirs[0] + DIR_DELIM "file1",
|
||||||
|
dirs[1] + DIR_DELIM "file2"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto &it : dirs)
|
||||||
|
fs::CreateDir(it);
|
||||||
|
for (auto &it : files)
|
||||||
|
open_ofstream(it.c_str(), false).close();
|
||||||
|
|
||||||
|
for (auto &it : dirs)
|
||||||
|
UASSERT(fs::IsDir(it));
|
||||||
|
for (auto &it : files)
|
||||||
|
UASSERT(fs::IsFile(it));
|
||||||
|
|
||||||
|
UASSERT(fs::RecursiveDelete(dirs[0]));
|
||||||
|
|
||||||
|
for (auto &it : dirs)
|
||||||
|
UASSERT(!fs::IsDir(it));
|
||||||
|
for (auto &it : files)
|
||||||
|
UASSERT(!fs::IsFile(it));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user