fs_helpers.h raw

   1  // Copyright (c) 2009-2010 Satoshi Nakamoto
   2  // Copyright (c) 2009-2023 The Limenka 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 LIMENKA_UTIL_FS_HELPERS_H
   7  #define LIMENKA_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  
  17  /**
  18   * Ensure file contents are fully committed to disk, using a platform-specific
  19   * feature analogous to fsync().
  20   */
  21  bool FileCommit(FILE* file);
  22  
  23  /**
  24   * Sync directory contents. This is required on some environments to ensure that
  25   * newly created files are committed to disk.
  26   */
  27  void DirectoryCommit(const fs::path& dirname);
  28  
  29  bool TruncateFile(FILE* file, unsigned int length);
  30  int RaiseFileDescriptorLimit(int nMinFD);
  31  void AllocateFileRange(FILE* file, unsigned int offset, unsigned int length);
  32  
  33  /**
  34   * Rename src to dest.
  35   * @return true if the rename was successful.
  36   */
  37  [[nodiscard]] bool RenameOver(fs::path src, fs::path dest);
  38  
  39  namespace util {
  40  enum class LockResult {
  41      Success,
  42      ErrorWrite,
  43      ErrorLock,
  44  };
  45  [[nodiscard]] LockResult LockDirectory(const fs::path& directory, const fs::path& lockfile_name, bool probe_only = false);
  46  } // namespace util
  47  void UnlockDirectory(const fs::path& directory, const fs::path& lockfile_name);
  48  bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes = 0);
  49  
  50  /** Get the size of a file by scanning it.
  51   *
  52   * @param[in] path The file path
  53   * @param[in] max Stop seeking beyond this limit
  54   * @return The file size or max
  55   */
  56  std::streampos GetFileSize(const char* path, std::streamsize max = std::numeric_limits<std::streamsize>::max());
  57  
  58  //! Return the original FILE* unchanged. On systems that support it,
  59  //! also advise the OS that the file will be accessed sequentially.
  60  FILE* AdviseSequential(FILE*);
  61  
  62  //! Close a file and return the result of fclose(). On systems that
  63  //! support it, advise the OS to remove the file contents from the page
  64  //! cache (which can help on memory-constrained systems).
  65  int CloseAndUncache(FILE*);
  66  
  67  /** Release all directory locks. This is used for unit testing only, at runtime
  68   * the global destructor will take care of the locks.
  69   */
  70  void ReleaseDirectoryLocks();
  71  
  72  bool TryCreateDirectories(const fs::path& p);
  73  fs::path GetDefaultDataDir();
  74  
  75  /** Convert fs::perms to symbolic string of the form 'rwxrwxrwx'
  76   *
  77   * @param[in] p the perms to be converted
  78   * @return Symbolic permissions string
  79   */
  80  std::string PermsToSymbolicString(fs::perms p);
  81  /** Interpret a custom permissions level string as fs::perms
  82   *
  83   * @param[in] s Permission level string
  84   * @return Permissions as fs::perms
  85   */
  86  std::optional<fs::perms> InterpretPermString(const std::string& s);
  87  
  88  /** Check if a directory is writable by creating a temporary file on it.
  89   *
  90   * @param[in] dir_path Path of the directory to test
  91   * @return true if a temporary file could be created and removed, false otherwise.
  92   * @throw std::runtime_error if dir_path is not a directory.
  93   */
  94  bool IsDirWritable(const fs::path& dir_path);
  95  
  96  #ifdef WIN32
  97  fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
  98  #endif
  99  
 100  /** Determine whether the given path is a symbolic link or a reparse point on windows
 101   *
 102   * @param[in] path The path to check
 103   * @return Whether path is a symlink or reparse point
 104   */
 105  bool IsSymlink(const fs::path& path);
 106  
 107  #endif // LIMENKA_UTIL_FS_HELPERS_H
 108