dir_reader_linux.h revision c407dc5cd9bdc5668497f21b26b09d988ab439de
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 8#include <errno.h> 9#include <fcntl.h> 10#include <stdint.h> 11#include <sys/syscall.h> 12#include <unistd.h> 13 14#include "base/logging.h" 15#include "base/eintr_wrapper.h" 16 17// See the comments in dir_reader_posix.h about this. 18 19namespace base { 20 21struct linux_dirent { 22 uint64_t d_ino; 23 int64_t d_off; 24 unsigned short d_reclen; 25 unsigned char d_type; 26 char d_name[0]; 27}; 28 29class DirReaderLinux { 30 public: 31 explicit DirReaderLinux(const char* directory_path) 32 : fd_(open(directory_path, O_RDONLY | O_DIRECTORY)), 33 offset_(0), 34 size_(0) { 35 } 36 37 ~DirReaderLinux() { 38 if (fd_ >= 0) { 39 if (HANDLE_EINTR(close(fd_))) 40 RAW_LOG(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 linux_dirent* dirent = reinterpret_cast<linux_dirent*>(&buf_[offset_]); 52 offset_ += dirent->d_reclen; 53 } 54 55 if (offset_ != size_) 56 return true; 57 58 const int r = syscall(__NR_getdents64, fd_, buf_, sizeof(buf_)); 59 if (r == 0) 60 return false; 61 if (r == -1) { 62 DPLOG(FATAL) << "getdents64 returned an error: " << errno; 63 return false; 64 } 65 size_ = r; 66 offset_ = 0; 67 return true; 68 } 69 70 const char* name() const { 71 if (!size_) 72 return NULL; 73 74 const linux_dirent* dirent = 75 reinterpret_cast<const linux_dirent*>(&buf_[offset_]); 76 return dirent->d_name; 77 } 78 79 int fd() const { 80 return fd_; 81 } 82 83 static bool IsFallback() { 84 return false; 85 } 86 87 private: 88 const int fd_; 89 unsigned char buf_[512]; 90 size_t offset_, size_; 91 92 DISALLOW_COPY_AND_ASSIGN(DirReaderLinux); 93}; 94 95} // namespace base 96 97#endif // BASE_DIR_READER_LINUX_H_ 98