[Lldb-commits] [PATCH] Replace `rm -rf` with more portable implementation.
Greg Clayton
clayborg at gmail.com
Mon Jun 29 10:35:38 PDT 2015
See inlined comments for needed changes.
REPOSITORY
rL LLVM
================
Comment at: lldb/trunk/source/Host/posix/FileSystem.cpp:85-103
@@ -83,7 +84,21 @@
{
- StreamString command;
- command.Printf("rm -rf \"%s\"", file_spec.GetCString());
- int status = ::system(command.GetString().c_str());
- if (status != 0)
- error.SetError(status, eErrorTypeGeneric);
+ DIR *dirp = opendir(file_spec.GetCString());
+ if (!dirp)
+ {
+ error.SetErrorToErrno();
+ return error;
+ }
+ struct dirent *direntp;
+ while (error.Success() && (direntp = readdir(dirp)))
+ {
+ if (direntp->d_type == DT_DIR)
+ error = DeleteDirectory(FileSpec{direntp->d_name, false}, true);
+ else if (::unlink(direntp->d_name) != 0)
+ error.SetErrorToErrno();
+ }
+ if (closedir(dirp) != 0)
+ error.SetErrorToErrno();
+ if (error.Fail())
+ return error;
+ return DeleteDirectory(file_spec, false);
}
----------------
Please fix the following things:
1 - use FileSpec::EnumerateDirectory(...) instead of using opendir(), readdir(), closedir() directly
2 - Save the directories up in a std::vector and process them _after_ the call the FileSpec::EnumerateDirectory(...) has completed iterating through the current directory so we don't run out of file descriptors when we try to delete a directory that has 1000000 entries inside of it. Each opendir()/closedir() takes up a file descriptor and if you recursively call this function you will run out of fds. You want to avoid the recursive nature here and only use 1 file descriptor at a time for the recursion by just saving the list of directories to delete, then iterating through those directories and calling FileSystem::DeleteDirectory() with each item.
Extra credit for possibly making a new version of FileSpec::EnumerateDirectory(...) that uses a lambda instead of a callback. Something like:
typedef std::function < FileSpec::EnumerateDirectoryResult(FileType file_type, const FileSpec &spec)> FileCallback;
FileSpec::EnumerateDirectoryResult
FileSpec::ForEachDirectory (const char *dir_path,
bool find_directories,
bool find_files,
bool find_other,
FileCallback const& callback);
http://reviews.llvm.org/D10787
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
More information about the lldb-commits
mailing list