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: DirReaderLinux(const char * directory_path)32 explicit DirReaderLinux(const char* directory_path) 33 : fd_(open(directory_path, O_RDONLY | O_DIRECTORY)), 34 offset_(0), 35 size_(0) { 36 } 37 ~DirReaderLinux()38 ~DirReaderLinux() { 39 if (fd_ >= 0) { 40 if (HANDLE_EINTR(close(fd_))) 41 RAW_LOG(ERROR, "Failed to close directory handle"); 42 } 43 } 44 IsValid()45 bool IsValid() const { 46 return fd_ >= 0; 47 } 48 49 // Move to the next entry returning false if the iteration is complete. Next()50 bool Next() { 51 if (size_) { 52 linux_dirent* dirent = reinterpret_cast<linux_dirent*>(&buf_[offset_]); 53 offset_ += dirent->d_reclen; 54 } 55 56 if (offset_ != size_) 57 return true; 58 59 const int r = syscall(__NR_getdents64, fd_, buf_, sizeof(buf_)); 60 if (r == 0) 61 return false; 62 if (r == -1) { 63 DPLOG(FATAL) << "getdents64 returned an error: " << errno; 64 return false; 65 } 66 size_ = r; 67 offset_ = 0; 68 return true; 69 } 70 name()71 const char* name() const { 72 if (!size_) 73 return NULL; 74 75 const linux_dirent* dirent = 76 reinterpret_cast<const linux_dirent*>(&buf_[offset_]); 77 return dirent->d_name; 78 } 79 fd()80 int fd() const { 81 return fd_; 82 } 83 IsFallback()84 static bool IsFallback() { 85 return false; 86 } 87 88 private: 89 const int fd_; 90 unsigned char buf_[512]; 91 size_t offset_, size_; 92 93 DISALLOW_COPY_AND_ASSIGN(DirReaderLinux); 94 }; 95 96 } // namespace base 97 98 #endif // BASE_DIR_READER_LINUX_H_ 99