1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- // Copyright 2022 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "net/disk_cache/simple/simple_file_enumerator.h"
- #include "base/files/file.h"
- #include "base/files/file_util.h"
- #include "base/logging.h"
- // We have an optimized implementation for POSIX, and a fallback
- // implementation for other platforms.
- namespace disk_cache {
- #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
- SimpleFileEnumerator::SimpleFileEnumerator(const base::FilePath& path)
- : path_(path), dir_(opendir(path.value().c_str())), has_error_(!dir_) {
- if (has_error_) {
- PLOG(ERROR) << "opendir " << path;
- }
- }
- SimpleFileEnumerator::~SimpleFileEnumerator() = default;
- bool SimpleFileEnumerator::HasError() const {
- return has_error_;
- }
- absl::optional<SimpleFileEnumerator::Entry> SimpleFileEnumerator::Next() {
- if (!dir_) {
- return absl::nullopt;
- }
- while (true) {
- // errno must be set to 0 before every readdir() call to detect errors.
- errno = 0;
- dirent* entry = readdir(dir_.get());
- if (!entry) {
- // Some implementations of readdir() (particularly older versions of
- // Android Bionic) may leave errno set to EINTR even after they handle
- // this case internally. It's safe to ignore EINTR in that case.
- if (errno && errno != EINTR) {
- PLOG(ERROR) << "readdir " << path_;
- has_error_ = true;
- dir_ = nullptr;
- return absl::nullopt;
- }
- break;
- }
- const std::string filename(entry->d_name);
- if (filename == "." || filename == "..") {
- continue;
- }
- base::FilePath path = path_.Append(base::FilePath(filename));
- base::File::Info file_info;
- if (!base::GetFileInfo(path, &file_info)) {
- LOG(ERROR) << "Could not get file info for " << path;
- continue;
- }
- if (file_info.is_directory) {
- continue;
- }
- return absl::make_optional<Entry>(std::move(path), file_info.size,
- file_info.last_accessed,
- file_info.last_modified);
- }
- dir_ = nullptr;
- return absl::nullopt;
- }
- #else
- SimpleFileEnumerator::SimpleFileEnumerator(const base::FilePath& path)
- : enumerator_(path,
- /*recursive=*/false,
- base::FileEnumerator::FILES) {}
- SimpleFileEnumerator::~SimpleFileEnumerator() = default;
- bool SimpleFileEnumerator::HasError() const {
- return enumerator_.GetError() != base::File::FILE_OK;
- }
- absl::optional<SimpleFileEnumerator::Entry> SimpleFileEnumerator::Next() {
- base::FilePath path = enumerator_.Next();
- if (path.empty()) {
- return absl::nullopt;
- }
- base::FileEnumerator::FileInfo info = enumerator_.GetInfo();
- return absl::make_optional<Entry>(std::move(path), info.GetSize(),
- /*last_accessed=*/base::Time(),
- info.GetLastModifiedTime());
- }
- #endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
- } // namespace disk_cache
|