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