1 : // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef BASE_DIR_READER_LINUX_H_
6 : #define BASE_DIR_READER_LINUX_H_
7 : #pragma once
8 :
9 : #include <errno.h>
10 : #include <fcntl.h>
11 : #include <stdint.h>
12 : #include <sys/syscall.h>
13 : #include <unistd.h>
14 :
15 : #include "base/logging.h"
16 : #include "base/eintr_wrapper.h"
17 :
18 : // See the comments in dir_reader_posix.h about this.
19 :
20 : namespace base {
21 :
22 : struct linux_dirent {
23 : uint64_t d_ino;
24 : int64_t d_off;
25 : unsigned short d_reclen;
26 : unsigned char d_type;
27 : char d_name[0];
28 : };
29 :
30 : class DirReaderLinux {
31 : public:
32 0 : explicit DirReaderLinux(const char* directory_path)
33 0 : : fd_(open(directory_path, O_RDONLY | O_DIRECTORY)),
34 : offset_(0),
35 0 : size_(0) {
36 0 : memset(buf_, 0, sizeof(buf_));
37 0 : }
38 :
39 0 : ~DirReaderLinux() {
40 0 : if (fd_ >= 0) {
41 0 : if (HANDLE_EINTR(close(fd_)))
42 0 : DLOG(ERROR) << "Failed to close directory handle";
43 : }
44 0 : }
45 :
46 0 : bool IsValid() const {
47 0 : return fd_ >= 0;
48 : }
49 :
50 : // Move to the next entry returning false if the iteration is complete.
51 0 : bool Next() {
52 0 : if (size_) {
53 0 : linux_dirent* dirent = reinterpret_cast<linux_dirent*>(&buf_[offset_]);
54 0 : offset_ += dirent->d_reclen;
55 : }
56 :
57 0 : if (offset_ != size_)
58 0 : return true;
59 :
60 0 : const int r = syscall(__NR_getdents64, fd_, buf_, sizeof(buf_));
61 0 : if (r == 0)
62 0 : return false;
63 0 : if (r == -1) {
64 0 : DLOG(ERROR) << "getdents64 returned an error: " << errno;
65 0 : return false;
66 : }
67 0 : size_ = r;
68 0 : offset_ = 0;
69 0 : return true;
70 : }
71 :
72 0 : const char* name() const {
73 0 : if (!size_)
74 0 : return NULL;
75 :
76 : const linux_dirent* dirent =
77 0 : reinterpret_cast<const linux_dirent*>(&buf_[offset_]);
78 0 : return dirent->d_name;
79 : }
80 :
81 0 : int fd() const {
82 0 : return fd_;
83 : }
84 :
85 : static bool IsFallback() {
86 : return false;
87 : }
88 :
89 : private:
90 : const int fd_;
91 : unsigned char buf_[512];
92 : size_t offset_, size_;
93 :
94 : DISALLOW_COPY_AND_ASSIGN(DirReaderLinux);
95 : };
96 :
97 : } // namespace base
98 :
99 : #endif // BASE_DIR_READER_LINUX_H_
|