tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

dir_reader_bsd.h (2132B)


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