diff options
author | 2010-08-27 11:41:07 +0100 | |
---|---|---|
committer | 2010-08-27 11:44:01 +0100 | |
commit | d6a8a3366ad7c8668be924753d29e930e86b2462 (patch) | |
tree | 3215a0f95ffbf87c134fc116e0883914d18f1dc0 | |
parent | 737643322e5b2308b0887d35561e6e03edf109ae (diff) | |
download | paludis-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.cc | 10 | ||||
-rw-r--r-- | paludis/ndbam.cc | 17 | ||||
-rw-r--r-- | paludis/repositories/e/e_repository.cc | 10 | ||||
-rw-r--r-- | paludis/repositories/e/exheres_layout.cc | 6 | ||||
-rw-r--r-- | paludis/repositories/e/traditional_layout.cc | 14 | ||||
-rw-r--r-- | paludis/repositories/e/vdb_repository.cc | 38 | ||||
-rw-r--r-- | paludis/util/fs_iterator.cc | 84 | ||||
-rw-r--r-- | paludis/util/fs_iterator.se | 14 |
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 7762b28bd..f0ceec47a 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 a4b2ae67d..7092defcb 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 e5ab9d713..bfea6ce1e 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 933267764..1f56a34c3 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 9279208da..9a6c2749d 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 cbdf0e353..e3eb95d3e 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 b7db239a4..dba44b809 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 6cbf44b71..ec2850463 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 |