123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- // Copyright (c) 2012 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.
- #ifndef BASE_FILES_DIR_READER_LINUX_H_
- #define BASE_FILES_DIR_READER_LINUX_H_
- #include <errno.h>
- #include <fcntl.h>
- #include <stddef.h>
- #include <stdint.h>
- #include <string.h>
- #include <sys/syscall.h>
- #include <unistd.h>
- #include "base/logging.h"
- #include "base/macros.h"
- #include "base/posix/eintr_wrapper.h"
- // See the comments in dir_reader_posix.h about this.
- namespace base {
- struct linux_dirent {
- uint64_t d_ino;
- int64_t d_off;
- unsigned short d_reclen;
- unsigned char d_type;
- char d_name[0];
- };
- class DirReaderLinux {
- public:
- explicit DirReaderLinux(const char* directory_path)
- : fd_(open(directory_path, O_RDONLY | O_DIRECTORY)),
- offset_(0),
- size_(0) {
- memset(buf_, 0, sizeof(buf_));
- }
- ~DirReaderLinux() {
- if (fd_ >= 0) {
- if (IGNORE_EINTR(close(fd_)))
- RAW_LOG(ERROR, "Failed to close directory handle");
- }
- }
- bool IsValid() const {
- return fd_ >= 0;
- }
- // Move to the next entry returning false if the iteration is complete.
- bool Next() {
- if (size_) {
- linux_dirent* dirent = reinterpret_cast<linux_dirent*>(&buf_[offset_]);
- offset_ += dirent->d_reclen;
- }
- if (offset_ != size_)
- return true;
- const int r = syscall(__NR_getdents64, fd_, buf_, sizeof(buf_));
- if (r == 0)
- return false;
- if (r == -1) {
- DPLOG(FATAL) << "getdents64 failed";
- return false;
- }
- size_ = r;
- offset_ = 0;
- return true;
- }
- const char* name() const {
- if (!size_)
- return nullptr;
- const linux_dirent* dirent =
- reinterpret_cast<const linux_dirent*>(&buf_[offset_]);
- return dirent->d_name;
- }
- int fd() const {
- return fd_;
- }
- static bool IsFallback() {
- return false;
- }
- private:
- const int fd_;
- alignas(linux_dirent) unsigned char buf_[512];
- size_t offset_;
- size_t size_;
- DISALLOW_COPY_AND_ASSIGN(DirReaderLinux);
- };
- } // namespace base
- #endif // BASE_FILES_DIR_READER_LINUX_H_
|