michael@0: // Copyright (c) 2010 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: // derived from dir_reader_linux.h michael@0: michael@0: #ifndef BASE_DIR_READER_BSD_H_ michael@0: #define BASE_DIR_READER_BSD_H_ michael@0: #pragma once michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #include "base/logging.h" michael@0: #include "base/eintr_wrapper.h" michael@0: michael@0: // See the comments in dir_reader_posix.h about this. michael@0: michael@0: namespace base { michael@0: michael@0: class DirReaderBSD { michael@0: public: michael@0: explicit DirReaderBSD(const char* directory_path) michael@0: #ifdef O_DIRECTORY michael@0: : fd_(open(directory_path, O_RDONLY | O_DIRECTORY)), michael@0: #else michael@0: : fd_(open(directory_path, O_RDONLY)), michael@0: #endif michael@0: offset_(0), michael@0: size_(0) { michael@0: memset(buf_, 0, sizeof(buf_)); michael@0: } michael@0: michael@0: ~DirReaderBSD() { michael@0: if (fd_ >= 0) { michael@0: if (HANDLE_EINTR(close(fd_))) michael@0: DLOG(ERROR) << "Failed to close directory handle"; michael@0: } michael@0: } michael@0: michael@0: bool IsValid() const { michael@0: return fd_ >= 0; michael@0: } michael@0: michael@0: // Move to the next entry returning false if the iteration is complete. michael@0: bool Next() { michael@0: if (size_) { michael@0: struct dirent* dirent = reinterpret_cast(&buf_[offset_]); michael@0: #ifdef OS_DRAGONFLY michael@0: offset_ += _DIRENT_DIRSIZ(dirent); michael@0: #else michael@0: offset_ += dirent->d_reclen; michael@0: #endif michael@0: } michael@0: michael@0: if (offset_ != size_) michael@0: return true; michael@0: michael@0: const int r = getdents(fd_, buf_, sizeof(buf_)); michael@0: if (r == 0) michael@0: return false; michael@0: if (r == -1) { michael@0: DLOG(ERROR) << "getdents returned an error: " << errno; michael@0: return false; michael@0: } michael@0: size_ = r; michael@0: offset_ = 0; michael@0: return true; michael@0: } michael@0: michael@0: const char* name() const { michael@0: if (!size_) michael@0: return NULL; michael@0: michael@0: const struct dirent* dirent = michael@0: reinterpret_cast(&buf_[offset_]); michael@0: return dirent->d_name; michael@0: } michael@0: michael@0: int fd() const { michael@0: return fd_; michael@0: } michael@0: michael@0: static bool IsFallback() { michael@0: return false; michael@0: } michael@0: michael@0: private: michael@0: const int fd_; michael@0: char buf_[512]; michael@0: size_t offset_, size_; michael@0: michael@0: DISALLOW_COPY_AND_ASSIGN(DirReaderBSD); michael@0: }; michael@0: michael@0: } // namespace base michael@0: michael@0: #endif // BASE_DIR_READER_BSD_H_