FileLister (linux): Handle cyclic symbolic links

Keep a list of already seen directories.

The "udev" project f.e. has a directory with
a subdirectory that contains a symbolic link
back to the parent directory.
This commit is contained in:
Thomas Jarosch 2011-10-29 19:40:50 +02:00
parent 0f299aa9bf
commit a09011630d
2 changed files with 17 additions and 5 deletions

View File

@ -277,6 +277,7 @@ std::string FileLister::getAbsolutePath(const std::string& path)
void FileLister::recursiveAddFiles2(std::vector<std::string> &relative, void FileLister::recursiveAddFiles2(std::vector<std::string> &relative,
std::vector<std::string> &absolute, std::vector<std::string> &absolute,
std::set<std::string> &seen_dirs,
std::map<std::string, long> &filesizes, std::map<std::string, long> &filesizes,
const std::string &path) const std::string &path)
{ {
@ -292,12 +293,14 @@ void FileLister::recursiveAddFiles2(std::vector<std::string> &relative,
if (filename == "." || filename == ".." || filename.length() == 0) if (filename == "." || filename == ".." || filename.length() == 0)
continue; continue;
if (filename[filename.length()-1] != '/') { // Determine absolute path. Empty filename if path does not exist
// File const std::string absolute_path = getAbsolutePath(filename);
std::string absolute_path = getAbsolutePath(filename);
if (absolute_path.empty()) if (absolute_path.empty())
continue; continue;
if (filename[filename.length()-1] != '/') {
// File
// Did we already see this file? Then bail out // Did we already see this file? Then bail out
if (std::find(absolute.begin(), absolute.end(), absolute_path) != absolute.end()) if (std::find(absolute.begin(), absolute.end(), absolute_path) != absolute.end())
continue; continue;
@ -313,7 +316,13 @@ void FileLister::recursiveAddFiles2(std::vector<std::string> &relative,
} }
} else { } else {
// Directory // Directory
recursiveAddFiles2(relative, absolute, filesizes, filename);
// Check if we already seen this part of the directory tree (cyclic symbolic links)
if (seen_dirs.find(absolute_path) != seen_dirs.end())
continue;
seen_dirs.insert(absolute_path);
recursiveAddFiles2(relative, absolute, seen_dirs, filesizes, filename);
} }
} }
globfree(&glob_results); globfree(&glob_results);
@ -323,7 +332,8 @@ void FileLister::recursiveAddFiles2(std::vector<std::string> &relative,
void FileLister::recursiveAddFiles(std::vector<std::string> &filenames, std::map<std::string, long> &filesizes, const std::string &path) void FileLister::recursiveAddFiles(std::vector<std::string> &filenames, std::map<std::string, long> &filesizes, const std::string &path)
{ {
std::vector<std::string> abs; std::vector<std::string> abs;
recursiveAddFiles2(filenames, abs, filesizes, path); std::set<std::string> seen_dirs;
recursiveAddFiles2(filenames, abs, seen_dirs, filesizes, path);
} }
bool FileLister::isDirectory(const std::string &path) bool FileLister::isDirectory(const std::string &path)

View File

@ -21,6 +21,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <set>
#include <map> #include <map>
/// @addtogroup CLI /// @addtogroup CLI
@ -67,6 +68,7 @@ public:
static void recursiveAddFiles2(std::vector<std::string> &relative, static void recursiveAddFiles2(std::vector<std::string> &relative,
std::vector<std::string> &absolute, std::vector<std::string> &absolute,
std::set<std::string> &seen_dirs,
std::map<std::string, long> &filesizes, std::map<std::string, long> &filesizes,
const std::string &path); const std::string &path);
#endif #endif