aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-02-20 21:02:26 +0000
committerlloyd <[email protected]>2012-02-20 21:02:26 +0000
commitec3d97c4b9cde8c017afa0f6c1dc7e69c6ac1229 (patch)
tree18ef4e70cd526447768dcd83e20150ca945d375e /src
parentcee8707b07952838e378ea7193af9eff83800b4e (diff)
Avoid having more than one directory open at a time by just keeping a
list of directory names (without the open DIRs) plus the one currently active dir.
Diffstat (limited to 'src')
-rw-r--r--src/entropy/proc_walk/es_ftw.cpp77
1 files changed, 49 insertions, 28 deletions
diff --git a/src/entropy/proc_walk/es_ftw.cpp b/src/entropy/proc_walk/es_ftw.cpp
index 7bf6c3310..8b4408aee 100644
--- a/src/entropy/proc_walk/es_ftw.cpp
+++ b/src/entropy/proc_walk/es_ftw.cpp
@@ -1,6 +1,6 @@
/*
* FTW EntropySource
-* (C) 1999-2008 Jack Lloyd
+* (C) 1999-2008,2012 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -41,60 +41,81 @@ namespace {
class Directory_Walker : public File_Descriptor_Source
{
public:
- Directory_Walker(const std::string& root) { add_directory(root); }
- ~Directory_Walker();
+ Directory_Walker(const std::string& root) :
+ m_cur_dir(std::make_pair<DIR*, std::string>(0, ""))
+ {
+ if(DIR* root_dir = ::opendir(root.c_str()))
+ m_cur_dir = std::make_pair(root_dir, root);
+ }
+
+ ~Directory_Walker()
+ {
+ if(m_cur_dir.first)
+ ::closedir(m_cur_dir.first);
+ }
int next_fd();
private:
- void add_directory(const std::string&);
+ void add_directory(const std::string& dirname)
+ {
+ m_dirlist.push_back(dirname);
+ }
- std::deque<std::pair<DIR*, std::string> > dirs;
- };
+ std::pair<struct dirent*, std::string> get_next_dirent();
-void Directory_Walker::add_directory(const std::string& dirname)
- {
- DIR* dir = ::opendir(dirname.c_str());
- if(dir)
- dirs.push_back(std::make_pair(dir, dirname));
- }
+ std::pair<DIR*, std::string> m_cur_dir;
+ std::deque<std::string> m_dirlist;
+ };
-Directory_Walker::~Directory_Walker()
+std::pair<struct dirent*, std::string> Directory_Walker::get_next_dirent()
{
- while(dirs.size())
+ while(m_cur_dir.first)
{
- ::closedir(dirs[0].first);
- dirs.pop_front();
+ struct dirent* dir = ::readdir(m_cur_dir.first);
+
+ if(dir)
+ return std::make_pair<struct dirent*, std::string>(dir, m_cur_dir.second);
+
+ ::closedir(m_cur_dir.first);
+ m_cur_dir = std::make_pair<DIR*, std::string>(0, "");
+
+ while(!m_dirlist.empty() && m_cur_dir.first == 0)
+ {
+ const std::string next_dir_name = m_dirlist[0];
+ m_dirlist.pop_front();
+
+ if(DIR* next_dir = ::opendir(next_dir_name.c_str()))
+ m_cur_dir = std::make_pair(next_dir, next_dir_name);
+ }
}
+
+ return std::make_pair<struct dirent*, std::string>(0, ""); // nothing left
}
int Directory_Walker::next_fd()
{
- while(dirs.size())
+ while(true)
{
- std::pair<DIR*, std::string> dirinfo = dirs[0];
+ std::pair<struct dirent*, std::string> entry = get_next_dirent();
- struct dirent* entry = ::readdir(dirinfo.first);
+ if(!entry.first)
+ break; // no more dirs
- if(!entry)
- {
- ::closedir(dirinfo.first);
- dirs.pop_front();
- continue;
- }
-
- const std::string filename = entry->d_name;
+ const std::string filename = entry.first->d_name;
if(filename == "." || filename == "..")
continue;
- const std::string full_path = dirinfo.second + '/' + filename;
+ const std::string full_path = entry.second + '/' + filename;
struct stat stat_buf;
if(::lstat(full_path.c_str(), &stat_buf) == -1)
continue;
if(S_ISDIR(stat_buf.st_mode))
+ {
add_directory(full_path);
+ }
else if(S_ISREG(stat_buf.st_mode) && (stat_buf.st_mode & S_IROTH))
{
int fd = ::open(full_path.c_str(), O_RDONLY | O_NOCTTY);