aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-27 11:41:07 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-27 11:44:01 +0100
commitd6a8a3366ad7c8668be924753d29e930e86b2462 (patch)
tree3215a0f95ffbf87c134fc116e0883914d18f1dc0
parent737643322e5b2308b0887d35561e6e03edf109ae (diff)
downloadpaludis-d6a8a3366ad7c8668be924753d29e930e86b2462.tar.gz
paludis-d6a8a3366ad7c8668be924753d29e930e86b2462.tar.xz
Make use of dirent->d_type if available
-rw-r--r--paludis/environments/no_config/no_config_environment.cc10
-rw-r--r--paludis/ndbam.cc17
-rw-r--r--paludis/repositories/e/e_repository.cc10
-rw-r--r--paludis/repositories/e/exheres_layout.cc6
-rw-r--r--paludis/repositories/e/traditional_layout.cc14
-rw-r--r--paludis/repositories/e/vdb_repository.cc38
-rw-r--r--paludis/util/fs_iterator.cc84
-rw-r--r--paludis/util/fs_iterator.se14
8 files changed, 117 insertions, 76 deletions
diff --git a/paludis/environments/no_config/no_config_environment.cc b/paludis/environments/no_config/no_config_environment.cc
index 7762b28..f0ceec4 100644
--- a/paludis/environments/no_config/no_config_environment.cc
+++ b/paludis/environments/no_config/no_config_environment.cc
@@ -116,17 +116,11 @@ namespace
}
int outer_count(0);
- for (FSIterator d(location, { }), d_end ; d != d_end ; ++d)
+ for (FSIterator d(location, { fsio_want_directories }), d_end ; d != d_end ; ++d)
{
- if (! d->stat().is_directory())
- continue;
-
int inner_count(0);
- for (FSIterator e(*d, { }), e_end ; e != e_end ; ++e)
+ for (FSIterator e(*d, { fsio_want_directories }), e_end ; e != e_end ; ++e)
{
- if (! e->stat().is_directory())
- continue;
-
if ((*e / "CONTENTS").stat().exists())
{
Log::get_instance()->message("no_config_environment.vdb_detected", ll_debug, lc_context)
diff --git a/paludis/ndbam.cc b/paludis/ndbam.cc
index a4b2ae6..7092def 100644
--- a/paludis/ndbam.cc
+++ b/paludis/ndbam.cc
@@ -150,11 +150,9 @@ NDBAM::category_names()
{
Context context("When loading category names for NDBAM at '" + stringify(_imp->location) + "':");
_imp->category_names = std::make_shared<CategoryNamePartSet>();
- for (FSIterator d(_imp->location / "indices" / "categories", { }), d_end ;
+ for (FSIterator d(_imp->location / "indices" / "categories", { fsio_want_directories, fsio_deref_symlinks_for_wants }), d_end ;
d != d_end ; ++d)
{
- if (! d->stat().is_directory_or_symlink_to_directory())
- continue;
if ('-' == d->basename().at(0))
continue;
@@ -195,11 +193,9 @@ NDBAM::package_names(const CategoryNamePart & c)
{
Context context("When loading package names in '" + stringify(c) + "' for NDBAM at '" + stringify(_imp->location) + "':");
cc.package_names = std::make_shared<QualifiedPackageNameSet>();
- for (FSIterator d(_imp->location / "indices" / "categories" / stringify(c), { }), d_end ;
+ for (FSIterator d(_imp->location / "indices" / "categories" / stringify(c), { fsio_want_directories, fsio_deref_symlinks_for_wants }), d_end ;
d != d_end ; ++d)
{
- if (! d->stat().is_directory_or_symlink_to_directory())
- continue;
if ('-' == d->basename().at(0))
continue;
@@ -309,11 +305,10 @@ NDBAM::entries(const QualifiedPackageName & q)
pc.entries = std::make_shared<NDBAMEntrySequence>();
Context context("When loading versions in '" + stringify(q) + "' for NDBAM at '" + stringify(_imp->location) + "':");
pc.entries = std::make_shared<NDBAMEntrySequence>();
- for (FSIterator d(_imp->location / "indices" / "categories" / stringify(q.category()) / stringify(q.package()), { }), d_end ;
+ for (FSIterator d(_imp->location / "indices" / "categories" / stringify(q.category()) / stringify(q.package()),
+ { fsio_want_directories, fsio_deref_symlinks_for_wants }), d_end ;
d != d_end ; ++d)
{
- if (! d->stat().is_directory_or_symlink_to_directory())
- continue;
if ('-' == d->basename().at(0))
continue;
@@ -614,10 +609,8 @@ NDBAM::category_names_containing_package(const PackageNamePart & p) const
FSPath dd(_imp->location / "indices" / "packages" / stringify(p));
if (dd.stat().is_directory_or_symlink_to_directory())
{
- for (FSIterator d(dd, { }), d_end ; d != d_end ; ++d)
+ for (FSIterator d(dd, { fsio_want_directories, fsio_deref_symlinks_for_wants }), d_end ; d != d_end ; ++d)
{
- if (! d->stat().is_directory_or_symlink_to_directory())
- continue;
if ('-' == d->basename().at(0))
continue;
diff --git a/paludis/repositories/e/e_repository.cc b/paludis/repositories/e/e_repository.cc
index e5ab9d7..bfea6ce 100644
--- a/paludis/repositories/e/e_repository.cc
+++ b/paludis/repositories/e/e_repository.cc
@@ -821,16 +821,10 @@ ERepository::purge_invalid_cache() const
if (master_mtime_file_stat.exists())
master_mtime = master_mtime_file_stat.mtim().seconds();
- for (FSIterator dc(write_cache, { fsio_inode_sort }), dc_end ; dc != dc_end ; ++dc)
+ for (FSIterator dc(write_cache, { fsio_inode_sort, fsio_want_directories, fsio_deref_symlinks_for_wants }), dc_end ; dc != dc_end ; ++dc)
{
- if (! dc->stat().is_directory_or_symlink_to_directory())
- continue;
-
- for (FSIterator dp(*dc, { fsio_inode_sort }), dp_end ; dp != dp_end ; ++dp)
+ for (FSIterator dp(*dc, { fsio_inode_sort, fsio_want_regular_files, fsio_deref_symlinks_for_wants }), dp_end ; dp != dp_end ; ++dp)
{
- if (! dp->stat().is_regular_file_or_symlink_to_regular_file())
- continue;
-
try
{
CategoryNamePart cnp(dc->basename());
diff --git a/paludis/repositories/e/exheres_layout.cc b/paludis/repositories/e/exheres_layout.cc
index 9332677..1f56a34 100644
--- a/paludis/repositories/e/exheres_layout.cc
+++ b/paludis/repositories/e/exheres_layout.cc
@@ -362,13 +362,11 @@ ExheresLayout::package_names(const CategoryNamePart & c) const
return std::make_shared<QualifiedPackageNameSet>();
if ((_imp->tree_root / "packages" / stringify(c)).stat().is_directory_or_symlink_to_directory())
- for (FSIterator d(_imp->tree_root / "packages" / stringify(c), { }), d_end ; d != d_end ; ++d)
+ for (FSIterator d(_imp->tree_root / "packages" / stringify(c), { fsio_want_directories, fsio_deref_symlinks_for_wants }), d_end ;
+ d != d_end ; ++d)
{
try
{
- if (! d->stat().is_directory_or_symlink_to_directory())
- continue;
-
if (d->basename() == "CVS")
continue;
diff --git a/paludis/repositories/e/traditional_layout.cc b/paludis/repositories/e/traditional_layout.cc
index 9279208..9a6c274 100644
--- a/paludis/repositories/e/traditional_layout.cc
+++ b/paludis/repositories/e/traditional_layout.cc
@@ -207,11 +207,8 @@ TraditionalLayout::need_category_names() const
{
Log::get_instance()->message("e.traditional_layout.categories.no_file", ll_qa, lc_context)
<< "No categories file for repository at '" << _imp->tree_root << "', faking it";
- for (FSIterator d(_imp->tree_root, { fsio_inode_sort }), d_end ; d != d_end ; ++d)
+ for (FSIterator d(_imp->tree_root, { fsio_inode_sort, fsio_deref_symlinks_for_wants, fsio_want_directories }), d_end ; d != d_end ; ++d)
{
- if (! d->stat().is_directory_or_symlink_to_directory())
- continue;
-
std::string n(d->basename());
if (n == "CVS" || n == "distfiles" || n == "scripts" || n == "eclass" || n == "licenses"
|| n == "packages")
@@ -373,13 +370,10 @@ TraditionalLayout::package_names(const CategoryNamePart & c) const
return std::make_shared<QualifiedPackageNameSet>();
if ((_imp->tree_root / stringify(c)).stat().is_directory_or_symlink_to_directory())
- for (FSIterator d(_imp->tree_root / stringify(c), { fsio_inode_sort }), d_end ; d != d_end ; ++d)
+ for (FSIterator d(_imp->tree_root / stringify(c), { fsio_inode_sort, fsio_deref_symlinks_for_wants, fsio_want_directories }), d_end ; d != d_end ; ++d)
{
try
{
- if (! d->stat().is_directory_or_symlink_to_directory())
- continue;
-
if (d->basename() == "CVS")
continue;
@@ -616,11 +610,11 @@ TraditionalLayout::manifest_files(const QualifiedPackageName & qpn) const
auto result(std::make_shared<Map<FSPath, std::string, FSPathComparator>>());
FSPath package_dir = _imp->repository->layout()->package_directory(qpn);
- std::list<FSPath> package_files((FSIterator(package_dir, { fsio_inode_sort })), FSIterator());
+ std::list<FSPath> package_files((FSIterator(package_dir, { fsio_inode_sort, fsio_want_regular_files })), FSIterator());
for (std::list<FSPath>::iterator f(package_files.begin()) ;
f != package_files.end() ; ++f)
{
- if (! f->stat().is_regular_file() || ((*f).basename() == "Manifest") )
+ if ((*f).basename() == "Manifest")
continue;
std::string file_type("MISC");
diff --git a/paludis/repositories/e/vdb_repository.cc b/paludis/repositories/e/vdb_repository.cc
index cbdf0e3..e3eb95d 100644
--- a/paludis/repositories/e/vdb_repository.cc
+++ b/paludis/repositories/e/vdb_repository.cc
@@ -1065,12 +1065,11 @@ VDBRepository::need_category_names() const
Context context("When loading category names from '" + stringify(_imp->params.location()) + "':");
- for (FSIterator d(_imp->params.location(), { fsio_inode_sort }), d_end ; d != d_end ; ++d)
+ for (FSIterator d(_imp->params.location(), { fsio_inode_sort, fsio_want_directories, fsio_deref_symlinks_for_wants }), d_end ; d != d_end ; ++d)
try
{
- if (d->stat().is_directory_or_symlink_to_directory())
- _imp->categories.insert(std::make_pair(CategoryNamePart(d->basename()),
- std::shared_ptr<QualifiedPackageNameSet>()));
+ _imp->categories.insert(std::make_pair(CategoryNamePart(d->basename()),
+ std::shared_ptr<QualifiedPackageNameSet>()));
}
catch (const InternalError &)
{
@@ -1098,23 +1097,21 @@ VDBRepository::need_package_ids(const CategoryNamePart & c) const
std::shared_ptr<QualifiedPackageNameSet> q(std::make_shared<QualifiedPackageNameSet>());
- for (FSIterator d(_imp->params.location() / stringify(c), { fsio_inode_sort }), d_end ; d != d_end ; ++d)
+ for (FSIterator d(_imp->params.location() / stringify(c), { fsio_inode_sort, fsio_want_directories, fsio_deref_symlinks_for_wants }), d_end ;
+ d != d_end ; ++d)
try
{
- if (d->stat().is_directory_or_symlink_to_directory())
- {
- std::string s(d->basename());
- if (std::string::npos == s.rfind('-'))
- continue;
+ std::string s(d->basename());
+ if (std::string::npos == s.rfind('-'))
+ continue;
- PackageDepSpec p(parse_user_package_dep_spec("=" + stringify(c) + "/" + s,
- _imp->params.environment(), { }));
- q->insert(*p.package_ptr());
- IDMap::iterator i(_imp->ids.find(*p.package_ptr()));
- if (_imp->ids.end() == i)
- i = _imp->ids.insert(std::make_pair(*p.package_ptr(), std::make_shared<PackageIDSequence>())).first;
- i->second->push_back(make_id(*p.package_ptr(), p.version_requirements_ptr()->begin()->version_spec(), *d));
- }
+ PackageDepSpec p(parse_user_package_dep_spec("=" + stringify(c) + "/" + s,
+ _imp->params.environment(), { }));
+ q->insert(*p.package_ptr());
+ IDMap::iterator i(_imp->ids.find(*p.package_ptr()));
+ if (_imp->ids.end() == i)
+ i = _imp->ids.insert(std::make_pair(*p.package_ptr(), std::make_shared<PackageIDSequence>())).first;
+ i->second->push_back(make_id(*p.package_ptr(), p.version_requirements_ptr()->begin()->version_spec(), *d));
}
catch (const InternalError &)
{
@@ -1387,14 +1384,11 @@ VDBRepository::perform_updates()
continue;
}
- for (FSIterator d(k->value(), { }), d_end ; d != d_end ; ++d)
+ for (FSIterator d(k->value(), { fsio_want_directories, fsio_deref_symlinks_for_wants }), d_end ; d != d_end ; ++d)
{
Context context_3("When performing updates from '" + stringify(*d) + "':");
FSStat d_stat(*d);
- if (! d_stat.is_regular_file_or_symlink_to_regular_file())
- continue;
-
update_timestamps.insert(std::make_pair(*d, d_stat.mtim().seconds()));
std::map<FSPath, std::time_t, FSPathComparator>::const_iterator last_checked(cache_contents.find(*d));
if (cache_contents.end() != last_checked && d_stat.mtim().seconds() <= last_checked->second)
diff --git a/paludis/util/fs_iterator.cc b/paludis/util/fs_iterator.cc
index b7db239..dba44b8 100644
--- a/paludis/util/fs_iterator.cc
+++ b/paludis/util/fs_iterator.cc
@@ -21,10 +21,12 @@
#include <paludis/util/fs_iterator.hh>
#include <paludis/util/fs_path.hh>
#include <paludis/util/fs_error.hh>
+#include <paludis/util/fs_stat.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/exception.hh>
#include <paludis/util/pimp-impl.hh>
#include <paludis/util/options.hh>
+#include <paludis/util/tribool.hh>
#include <dirent.h>
#include <sys/types.h>
@@ -80,26 +82,90 @@ FSIterator::FSIterator(const FSPath & base, const FSIteratorOptions & options) :
if (0 == d)
throw FSError("Error opening directory '" + stringify(base) + "'");
+ bool have_any_special_wants(options[fsio_want_directories] || options[fsio_want_regular_files]);
+
struct dirent * de;
+ bool done(false);
while (0 != ((de = readdir(d))))
+ {
+ if (done)
+ break;
+
+ bool want(false);
+
if (! options[fsio_include_dotfiles])
{
if ('.' != de->d_name[0])
- {
- FSPath f(stringify(base / std::string(de->d_name)));
- _imp->items->insert(std::make_pair(de->d_ino, f));
- if (options[fsio_first_only])
- break;
- }
+ want = true;
}
else if (! (de->d_name[0] == '.' &&
(de->d_name[1] == '\0' || (de->d_name[1] == '.' && de->d_name[2] == '\0'))))
+ want = true;
+
+ if (want)
{
FSPath f(stringify(base / std::string(de->d_name)));
- _imp->items->insert(std::make_pair(de->d_ino, f));
- if (options[fsio_first_only])
- break;
+
+ if (have_any_special_wants)
+ {
+ Tribool still_want(indeterminate);
+
+#ifdef HAVE_DIRENT_DTYPE
+ if (DT_UNKNOWN != de->d_type)
+ {
+ int s(DTTOIF(de->d_type));
+
+ if (S_ISLNK(s))
+ {
+ if (! options[fsio_deref_symlinks_for_wants])
+ still_want = false;
+ }
+ else if (S_ISREG(s))
+ still_want = options[fsio_want_regular_files];
+ else if (S_ISDIR(s))
+ still_want = options[fsio_want_directories];
+ else
+ still_want = false;
+ }
+#endif
+
+ if (still_want.is_indeterminate())
+ {
+ FSStat f_stat(f);
+
+ if (f_stat.is_regular_file())
+ still_want = options[fsio_want_regular_files];
+ else if (f_stat.is_directory())
+ still_want = options[fsio_want_directories];
+ else if (f_stat.is_symlink())
+ {
+ if (options[fsio_deref_symlinks_for_wants])
+ {
+ if (f_stat.is_regular_file_or_symlink_to_regular_file())
+ still_want = options[fsio_want_regular_files];
+ else if (f_stat.is_directory_or_symlink_to_directory())
+ still_want = options[fsio_want_directories];
+ else
+ still_want = false;
+ }
+ else
+ still_want = false;
+ }
+ else
+ still_want = false;
+ }
+
+ want = still_want.is_true();
+ }
+
+ if (want)
+ {
+ _imp->items->insert(std::make_pair(de->d_ino, f));
+ if (options[fsio_first_only])
+ done = true;
+ }
}
+ }
_imp->iter = _imp->items->begin();
diff --git a/paludis/util/fs_iterator.se b/paludis/util/fs_iterator.se
index 6cbf44b..ec28504 100644
--- a/paludis/util/fs_iterator.se
+++ b/paludis/util/fs_iterator.se
@@ -5,14 +5,22 @@ make_enum_FSIteratorOption()
{
prefix fsio
- key fsio_include_dotfiles "Skip files whose name start with a dot"
- key fsio_inode_sort "Return items sorted by inode number"
- key fsio_first_only "Return the first item only"
+ key fsio_include_dotfiles "Skip files whose name start with a dot"
+ key fsio_inode_sort "Return items sorted by inode number"
+ key fsio_first_only "Return the first item only"
+
+ key fsio_want_directories "\since 0.54.1 We want directories"
+ key fsio_want_regular_files "\since 0.54.1 We want regular files"
+ key fsio_deref_symlinks_for_wants "\since 0.54.1 Dereference symlinks when determining wants"
doxygen_comment << "END"
/**
* Options for an FSIterator.
*
+ * If no fsio_want_ options are specified, all entries are always
+ * returned. Otherwise, entries will be skipped if their type is not
+ * any of the fsio_want_ types.
+ *
* \see FSIterator
* \see FSIteratorOptions
* \ingroup g_fs