reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
//===-- FileSystem.h --------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_Host_FileSystem_h
#define liblldb_Host_FileSystem_h

#include "lldb/Host/File.h"
#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Status.h"

#include "llvm/ADT/Optional.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/FileCollector.h"
#include "llvm/Support/VirtualFileSystem.h"

#include "lldb/lldb-types.h"

#include <stdint.h>
#include <stdio.h>
#include <sys/stat.h>

namespace lldb_private {
class FileSystem {
public:
  static const char *DEV_NULL;
  static const char *PATH_CONVERSION_ERROR;

  FileSystem()
      : m_fs(llvm::vfs::getRealFileSystem()), m_collector(nullptr),
        m_mapped(false) {}
  FileSystem(std::shared_ptr<llvm::FileCollector> collector)
      : m_fs(llvm::vfs::getRealFileSystem()), m_collector(collector),
        m_mapped(false) {}
  FileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs,
             bool mapped = false)
      : m_fs(fs), m_collector(nullptr), m_mapped(mapped) {}

  FileSystem(const FileSystem &fs) = delete;
  FileSystem &operator=(const FileSystem &fs) = delete;

  static FileSystem &Instance();

  static void Initialize();
  static void Initialize(std::shared_ptr<llvm::FileCollector> collector);
  static llvm::Error Initialize(const FileSpec &mapping);
  static void Initialize(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs);
  static void Terminate();

  Status Symlink(const FileSpec &src, const FileSpec &dst);
  Status Readlink(const FileSpec &src, FileSpec &dst);

  Status ResolveSymbolicLink(const FileSpec &src, FileSpec &dst);

  /// Wraps ::fopen in a platform-independent way.
  FILE *Fopen(const char *path, const char *mode);

  /// Wraps ::open in a platform-independent way.
  int Open(const char *path, int flags, int mode);

  llvm::Expected<std::unique_ptr<File>>
  Open(const FileSpec &file_spec, File::OpenOptions options,
       uint32_t permissions = lldb::eFilePermissionsFileDefault,
       bool should_close_fd = true);

  /// Get a directory iterator.
  /// \{
  llvm::vfs::directory_iterator DirBegin(const FileSpec &file_spec,
                                         std::error_code &ec);
  llvm::vfs::directory_iterator DirBegin(const llvm::Twine &dir,
                                         std::error_code &ec);
  /// \}

  /// Returns the Status object for the given file.
  /// \{
  llvm::ErrorOr<llvm::vfs::Status> GetStatus(const FileSpec &file_spec) const;
  llvm::ErrorOr<llvm::vfs::Status> GetStatus(const llvm::Twine &path) const;
  /// \}

  /// Returns the modification time of the given file.
  /// \{
  llvm::sys::TimePoint<> GetModificationTime(const FileSpec &file_spec) const;
  llvm::sys::TimePoint<> GetModificationTime(const llvm::Twine &path) const;
  /// \}

  /// Returns the on-disk size of the given file in bytes.
  /// \{
  uint64_t GetByteSize(const FileSpec &file_spec) const;
  uint64_t GetByteSize(const llvm::Twine &path) const;
  /// \}

  /// Return the current permissions of the given file.
  ///
  /// Returns a bitmask for the current permissions of the file (zero or more
  /// of the permission bits defined in File::Permissions).
  /// \{
  uint32_t GetPermissions(const FileSpec &file_spec) const;
  uint32_t GetPermissions(const llvm::Twine &path) const;
  uint32_t GetPermissions(const FileSpec &file_spec, std::error_code &ec) const;
  uint32_t GetPermissions(const llvm::Twine &path, std::error_code &ec) const;
  /// \}

  /// Returns whether the given file exists.
  /// \{
  bool Exists(const FileSpec &file_spec) const;
  bool Exists(const llvm::Twine &path) const;
  /// \}

  /// Returns whether the given file is readable.
  /// \{
  bool Readable(const FileSpec &file_spec) const;
  bool Readable(const llvm::Twine &path) const;
  /// \}

  /// Returns whether the given path is a directory.
  /// \{
  bool IsDirectory(const FileSpec &file_spec) const;
  bool IsDirectory(const llvm::Twine &path) const;
  /// \}

  /// Returns whether the given path is local to the file system.
  /// \{
  bool IsLocal(const FileSpec &file_spec) const;
  bool IsLocal(const llvm::Twine &path) const;
  /// \}

  /// Make the given file path absolute.
  /// \{
  std::error_code MakeAbsolute(llvm::SmallVectorImpl<char> &path) const;
  std::error_code MakeAbsolute(FileSpec &file_spec) const;
  /// \}

  /// Resolve path to make it canonical.
  /// \{
  void Resolve(llvm::SmallVectorImpl<char> &path);
  void Resolve(FileSpec &file_spec);
  /// \}

  //// Create memory buffer from path.
  /// \{
  std::shared_ptr<DataBufferLLVM> CreateDataBuffer(const llvm::Twine &path,
                                                   uint64_t size = 0,
                                                   uint64_t offset = 0);
  std::shared_ptr<DataBufferLLVM> CreateDataBuffer(const FileSpec &file_spec,
                                                   uint64_t size = 0,
                                                   uint64_t offset = 0);
  /// \}

  /// Call into the Host to see if it can help find the file.
  bool ResolveExecutableLocation(FileSpec &file_spec);

  enum EnumerateDirectoryResult {
    /// Enumerate next entry in the current directory.
    eEnumerateDirectoryResultNext,
    /// Recurse into the current entry if it is a directory or symlink, or next
    /// if not.
    eEnumerateDirectoryResultEnter,
    /// Stop directory enumerations at any level.
    eEnumerateDirectoryResultQuit
  };

  typedef EnumerateDirectoryResult (*EnumerateDirectoryCallbackType)(
      void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef);

  typedef std::function<EnumerateDirectoryResult(
      llvm::sys::fs::file_type file_type, llvm::StringRef)>
      DirectoryCallback;

  void EnumerateDirectory(llvm::Twine path, bool find_directories,
                          bool find_files, bool find_other,
                          EnumerateDirectoryCallbackType callback,
                          void *callback_baton);

  std::error_code GetRealPath(const llvm::Twine &path,
                              llvm::SmallVectorImpl<char> &output) const;

  llvm::ErrorOr<std::string> GetExternalPath(const llvm::Twine &path);
  llvm::ErrorOr<std::string> GetExternalPath(const FileSpec &file_spec);

  llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> GetVirtualFileSystem() {
    return m_fs;
  }

private:
  static llvm::Optional<FileSystem> &InstanceImpl();
  llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> m_fs;
  std::shared_ptr<llvm::FileCollector> m_collector;
  bool m_mapped;
};
} // namespace lldb_private

#endif