|
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 // derived from dir_reader_linux.h |
|
6 |
|
7 #ifndef BASE_DIR_READER_BSD_H_ |
|
8 #define BASE_DIR_READER_BSD_H_ |
|
9 #pragma once |
|
10 |
|
11 #include <dirent.h> |
|
12 #include <errno.h> |
|
13 #include <fcntl.h> |
|
14 #include <stdint.h> |
|
15 #include <unistd.h> |
|
16 |
|
17 #include "base/logging.h" |
|
18 #include "base/eintr_wrapper.h" |
|
19 |
|
20 // See the comments in dir_reader_posix.h about this. |
|
21 |
|
22 namespace base { |
|
23 |
|
24 class DirReaderBSD { |
|
25 public: |
|
26 explicit DirReaderBSD(const char* directory_path) |
|
27 #ifdef O_DIRECTORY |
|
28 : fd_(open(directory_path, O_RDONLY | O_DIRECTORY)), |
|
29 #else |
|
30 : fd_(open(directory_path, O_RDONLY)), |
|
31 #endif |
|
32 offset_(0), |
|
33 size_(0) { |
|
34 memset(buf_, 0, sizeof(buf_)); |
|
35 } |
|
36 |
|
37 ~DirReaderBSD() { |
|
38 if (fd_ >= 0) { |
|
39 if (HANDLE_EINTR(close(fd_))) |
|
40 DLOG(ERROR) << "Failed to close directory handle"; |
|
41 } |
|
42 } |
|
43 |
|
44 bool IsValid() const { |
|
45 return fd_ >= 0; |
|
46 } |
|
47 |
|
48 // Move to the next entry returning false if the iteration is complete. |
|
49 bool Next() { |
|
50 if (size_) { |
|
51 struct dirent* dirent = reinterpret_cast<struct dirent*>(&buf_[offset_]); |
|
52 #ifdef OS_DRAGONFLY |
|
53 offset_ += _DIRENT_DIRSIZ(dirent); |
|
54 #else |
|
55 offset_ += dirent->d_reclen; |
|
56 #endif |
|
57 } |
|
58 |
|
59 if (offset_ != size_) |
|
60 return true; |
|
61 |
|
62 const int r = getdents(fd_, buf_, sizeof(buf_)); |
|
63 if (r == 0) |
|
64 return false; |
|
65 if (r == -1) { |
|
66 DLOG(ERROR) << "getdents returned an error: " << errno; |
|
67 return false; |
|
68 } |
|
69 size_ = r; |
|
70 offset_ = 0; |
|
71 return true; |
|
72 } |
|
73 |
|
74 const char* name() const { |
|
75 if (!size_) |
|
76 return NULL; |
|
77 |
|
78 const struct dirent* dirent = |
|
79 reinterpret_cast<const struct dirent*>(&buf_[offset_]); |
|
80 return dirent->d_name; |
|
81 } |
|
82 |
|
83 int fd() const { |
|
84 return fd_; |
|
85 } |
|
86 |
|
87 static bool IsFallback() { |
|
88 return false; |
|
89 } |
|
90 |
|
91 private: |
|
92 const int fd_; |
|
93 char buf_[512]; |
|
94 size_t offset_, size_; |
|
95 |
|
96 DISALLOW_COPY_AND_ASSIGN(DirReaderBSD); |
|
97 }; |
|
98 |
|
99 } // namespace base |
|
100 |
|
101 #endif // BASE_DIR_READER_BSD_H_ |