fs_helpers.h raw

   1  // Copyright (c) 2009-2010 Satoshi Nakamoto
   2  // Copyright (c) 2009-present The Bitcoin Core developers
   3  // Distributed under the MIT software license, see the accompanying
   4  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   5  
   6  #ifndef BITCOIN_UTIL_FS_HELPERS_H
   7  #define BITCOIN_UTIL_FS_HELPERS_H
   8  
   9  #include <util/fs.h>
  10  
  11  #include <cstdint>
  12  #include <cstdio>
  13  #include <iosfwd>
  14  #include <limits>
  15  #include <optional>
  16  #include <string>
  17  
  18  #ifdef __APPLE__
  19  enum class FSType {
  20      EXFAT,
  21      OTHER,
  22      ERROR
  23  };
  24  
  25  /**
  26   * Detect filesystem type for a given path.
  27   * Currently identifies exFAT filesystems which cause issues on macOS.
  28   *
  29   * @param[in] path The directory path to check
  30   * @return FSType enum indicating the filesystem type
  31   */
  32  FSType GetFilesystemType(const fs::path& path);
  33  #endif
  34  
  35  /**
  36   * Ensure file contents are fully committed to disk, using a platform-specific
  37   * feature analogous to fsync().
  38   */
  39  bool FileCommit(FILE* file);
  40  
  41  /**
  42   * Sync directory contents. This is required on some environments to ensure that
  43   * newly created files are committed to disk.
  44   */
  45  void DirectoryCommit(const fs::path& dirname);
  46  
  47  bool TruncateFile(FILE* file, unsigned int length);
  48  
  49  /**
  50   * Try to raise the file descriptor limit to the requested number.
  51   *
  52   * @param[in] min_fd  The requested minimum number of file descriptors.
  53   * @returns           The actual file descriptor limit. It may be lower or
  54   *                    higher than min_fd. Returns std::numeric_limits<int>::max()
  55   *                    if the OS imposes no limit (RLIM_INFINITY).
  56   *
  57   */
  58  int RaiseFileDescriptorLimit(int min_fd);
  59  
  60  void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length);
  61  
  62  /**
  63   * Rename src to dest.
  64   * @return true if the rename was successful.
  65   */
  66  [[nodiscard]] bool RenameOver(fs::path src, fs::path dest);
  67  
  68  namespace util {
  69  enum class LockResult {
  70      Success,
  71      ErrorWrite,
  72      ErrorLock,
  73  };
  74  [[nodiscard]] LockResult LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only = false);
  75  } // namespace util
  76  void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name);
  77  bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0);
  78  
  79  /** Get the size of a file by scanning it.
  80   *
  81   * @param[in] path The file path
  82   * @param[in] max Stop seeking beyond this limit
  83   * @return The file size or max
  84   */
  85  std::streampos GetFileSize(const char* path, std::streamsize max = std::numeric_limits<std::streamsize>::max());
  86  
  87  /** Release all directory locks. This is used for unit testing only, at runtime
  88   * the global destructor will take care of the locks.
  89   */
  90  void ReleaseDirectoryLocks();
  91  
  92  bool TryCreateDirectories(const fs::path& p);
  93  fs::path GetDefaultDataDir();
  94  
  95  /** Convert fs::perms to symbolic string of the form 'rwxrwxrwx'
  96   *
  97   * @param[in] p the perms to be converted
  98   * @return Symbolic permissions string
  99   */
 100  std::string PermsToSymbolicString(fs::perms p);
 101  /** Interpret a custom permissions level string as fs::perms
 102   *
 103   * @param[in] s Permission level string
 104   * @return Permissions as fs::perms
 105   */
 106  std::optional<fs::perms> InterpretPermString(const std::string& s);
 107  
 108  /** Check if a directory is writable by creating a temporary file on it.
 109   *
 110   * @param[in] dir_path Path of the directory to test
 111   * @return true if a temporary file could be created and removed, false otherwise.
 112   * @throw std::runtime_error if dir_path is not a directory.
 113   */
 114  bool IsDirWritable(const fs::path& dir_path);
 115  
 116  #ifdef WIN32
 117  fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
 118  #endif
 119  
 120  #endif // BITCOIN_UTIL_FS_HELPERS_H
 121