| Index: base/dir_reader_linux.h
|
| diff --git a/base/dir_reader_linux.h b/base/dir_reader_linux.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7fd534f1f069701dfda03a769f3b91f1befefaac
|
| --- /dev/null
|
| +++ b/base/dir_reader_linux.h
|
| @@ -0,0 +1,97 @@
|
| +// Copyright (c) 2010 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_DIR_READER_LINUX_H_
|
| +#define BASE_DIR_READER_LINUX_H_
|
| +
|
| +#include <errno.h>
|
| +#include <fcntl.h>
|
| +#include <stdint.h>
|
| +#include <sys/syscall.h>
|
| +#include <unistd.h>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/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) {
|
| + }
|
| +
|
| + ~DirReaderLinux() {
|
| + if (fd_ >= 0) {
|
| + if (HANDLE_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 returned an error: " << errno;
|
| + return false;
|
| + }
|
| + size_ = r;
|
| + offset_ = 0;
|
| + return true;
|
| + }
|
| +
|
| + const char* name() const {
|
| + if (!size_)
|
| + return NULL;
|
| +
|
| + 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_;
|
| + unsigned char buf_[512];
|
| + size_t offset_, size_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DirReaderLinux);
|
| +};
|
| +
|
| +} // namespace base
|
| +
|
| +#endif // BASE_DIR_READER_LINUX_H_
|
|
|