X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gold%2Fdirsearch.cc;h=e8c9b1203c8e80809d587ad99af85434c75379d7;hb=1dadb1dd718f93801bcca669a0fb38e3da6177b8;hp=dd1c7e6eb2c884d4cb47b6f49027741787822b9c;hpb=c79126688f8211ab17a893c5e80b09811d424fc1;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/dirsearch.cc b/gold/dirsearch.cc index dd1c7e6eb2..e8c9b1203c 100644 --- a/gold/dirsearch.cc +++ b/gold/dirsearch.cc @@ -1,6 +1,6 @@ // dirsearch.cc -- directory searching for gold -// Copyright 2006, 2007 Free Software Foundation, Inc. +// Copyright (C) 2006-2020 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -25,9 +25,13 @@ #include #include #include +#include #include +#include "debug.h" #include "gold-threads.h" +#include "options.h" +#include "workqueue.h" #include "dirsearch.h" namespace @@ -63,8 +67,9 @@ Dir_cache::read_files() DIR* d = opendir(this->dirname_); if (d == NULL) { - // We ignore directories which do not exist. - if (errno != ENOENT) + // We ignore directories which do not exist or are actually file + // names. + if (errno != ENOENT && errno != ENOTDIR) gold::gold_error(_("%s: can not read directory: %s"), this->dirname_, strerror(errno)); return; @@ -97,7 +102,7 @@ class Dir_caches : lock_(), caches_() { } - ~Dir_caches(); + ~Dir_caches() ATTRIBUTE_UNUSED; // Add a cache for a directory. void add(const char*); @@ -169,11 +174,11 @@ class Dir_cache_task : public gold::Task : dir_(dir), token_(token) { } - Is_runnable_type - is_runnable(gold::Workqueue*); + gold::Task_token* + is_runnable(); - gold::Task_locker* - locks(gold::Workqueue*); + void + locks(gold::Task_locker*); void run(gold::Workqueue*); @@ -189,19 +194,19 @@ class Dir_cache_task : public gold::Task // We can always run the task to read the directory. -gold::Task::Is_runnable_type -Dir_cache_task::is_runnable(gold::Workqueue*) +gold::Task_token* +Dir_cache_task::is_runnable() { - return IS_RUNNABLE; + return NULL; } // Return the locks to hold. We use a blocker lock to prevent file // lookups from starting until the directory contents have been read. -gold::Task_locker* -Dir_cache_task::locks(gold::Workqueue* workqueue) +void +Dir_cache_task::locks(gold::Task_locker* tl) { - return new gold::Task_locker_block(this->token_, workqueue); + tl->add(this, &this->token_); } // Run the task--read the directory contents. @@ -217,6 +222,8 @@ Dir_cache_task::run(gold::Workqueue*) namespace gold { +// Initialize. + void Dirsearch::initialize(Workqueue* workqueue, const General_options::Dir_list* directories) @@ -224,41 +231,75 @@ Dirsearch::initialize(Workqueue* workqueue, gold_assert(caches == NULL); caches = new Dir_caches; this->directories_ = directories; + this->token_.add_blockers(directories->size()); for (General_options::Dir_list::const_iterator p = directories->begin(); p != directories->end(); ++p) - { - this->token_.add_blocker(); - workqueue->queue(new Dir_cache_task(p->name().c_str(), this->token_)); - } + workqueue->queue(new Dir_cache_task(p->name().c_str(), this->token_)); } +// Search for a file. NOTE: we only log failed file-lookup attempts +// here. Successfully lookups will eventually get logged in +// File_read::open. + std::string -Dirsearch::find(const std::string& n1, const std::string& n2, - bool *is_in_sysroot) const +Dirsearch::find(const std::vector& names, + bool* is_in_sysroot, int* pindex, + std::string *found_name) const { gold_assert(!this->token_.is_blocked()); + gold_assert(*pindex >= 0); - for (General_options::Dir_list::const_iterator p = - this->directories_->begin(); - p != this->directories_->end(); - ++p) + for (unsigned int i = static_cast(*pindex); + i < this->directories_->size(); + ++i) { + const Search_directory* p = &this->directories_->at(i); Dir_cache* pdc = caches->lookup(p->name().c_str()); gold_assert(pdc != NULL); - if (pdc->find(n1)) - { - *is_in_sysroot = p->is_in_sysroot(); - return p->name() + '/' + n1; - } - if (!n2.empty() && pdc->find(n2)) + for (std::vector::const_iterator n = names.begin(); + n != names.end(); + ++n) { - *is_in_sysroot = p->is_in_sysroot(); - return p->name() + '/' + n2; + if (pdc->find(*n)) + { + *is_in_sysroot = p->is_in_sysroot(); + *pindex = i; + *found_name = *n; + return p->name() + '/' + *n; + } + else + gold_debug(DEBUG_FILES, "Attempt to open %s/%s failed", + p->name().c_str(), (*n).c_str()); } } + *pindex = -2; return std::string(); } +// Search for a file in a directory list. This is a low-level function and +// therefore can be used before options and parameters are set. + +std::string +Dirsearch::find_file_in_dir_list(const std::string& name, + const General_options::Dir_list& directories, + const std::string& extra_search_dir) +{ + struct stat buf; + std::string extra_name = extra_search_dir + '/' + name; + + if (stat(extra_name.c_str(), &buf) == 0) + return extra_name; + for (General_options::Dir_list::const_iterator dir = directories.begin(); + dir != directories.end(); + ++dir) + { + std::string full_name = dir->name() + '/' + name; + if (stat(full_name.c_str(), &buf) == 0) + return full_name; + } + return name; +} + } // End namespace gold.