8 #ifdef SPH_USE_STD_EXPERIMENTAL
9 #include <experimental/filesystem>
15 std::ifstream t(path.
native().c_str());
16 std::stringstream buffer;
26 return (stat(path.
native().c_str(), &buffer) == 0);
30 std::ifstream ifs(path.
native(), std::ifstream::ate | std::ifstream::binary);
36 return access(path.
native().c_str(), W_OK) == 0;
40 const char* homeDir = getenv(
"HOME");
41 if (homeDir !=
nullptr) {
44 return makeUnexpected<Path>(
"Cannot obtain home directory");
49 char realPath[PATH_MAX];
50 realpath(relativePath.
native().c_str(), realPath);
51 return Path(realPath);
56 return makeUnexpected<PathType>(
"Path is empty");
59 if (stat(path.
native().c_str(), &buffer) != 0) {
61 return makeUnexpected<PathType>(
"Cannot retrieve type of the path");
63 if (S_ISREG(buffer.st_mode)) {
64 return PathType::FILE;
66 if (S_ISDIR(buffer.st_mode)) {
67 return PathType::DIRECTORY;
69 if (S_ISLNK(buffer.st_mode)) {
70 return PathType::SYMLINK;
72 return PathType::OTHER;
78 const bool result = mkdir(path.
native().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0;
83 "Search permission is denied on a component of the path prefix, or write permission is "
84 "denied on the parent directory of the directory to be created.");
93 "A loop exists in symbolic links encountered during resolution of the path argument.");
95 return makeFailed(
"The link count of the parent directory would exceed {LINK_MAX}.");
98 "The length of the path argument exceeds {PATH_MAX} or a pathname component is longer "
102 "A component of the path prefix specified by path does not name an existing directory "
103 "or path is an empty string.");
106 "The file system does not contain enough space to hold the contents of the new "
107 "directory or to extend the parent directory of the new directory.");
109 return makeFailed(
"A component of the path prefix is not a directory.");
111 return makeFailed(
"The parent directory resides on a read-only file system.");
120 #ifdef SPH_USE_STD_EXPERIMENTAL
121 return (
Outcome)std::experimental::filesystem::create_directories(path);
133 return createSingleDirectory(path, flags);
138 #ifdef SPH_USE_STD_EXPERIMENTAL
140 std::experimental::filesystem::remove_all(path);
141 }
catch (std::experimental::filesystem::filesystem_error& e) {
147 return makeFailed(
"Attempting to remove an empty path");
150 return makeFailed(
"Attemping to remove root. Pls, don't ...");
153 return makeFailed(
"Attemping to remove nonexisting path");
159 if (type.
value() == PathType::DIRECTORY && flags.
has(RemovePathFlag::RECURSIVE)) {
168 const bool result = (remove(path.
native().c_str()) == 0);
173 "Write access to the directory containing pathname was not allowed, or one of the "
174 "directories in the path prefix of pathname did not allow search permission.");
178 "is currently in use by the system or some process that prevents its removal.On "
179 "Linux this means pathname is currently used as a mount point or is the root directory of "
180 "the calling process.");
182 return makeFailed(
"Path " + path.
native() +
" points outside your accessible address space.");
186 return makeFailed(
"Too many symbolic links were encountered in resolving path " + path.
native());
191 " does not exist or is a dangling symbolic link.");
193 return makeFailed(
"Insufficient kernel memory was available.");
197 " or a component used as a directory in pathname, is not, in fact, a directory.");
201 " contains entries other than . and ..; or, pathname has .. as its final component.");
204 "The directory containing path " + path.
native() +
205 " has the sticky bit(S_ISVTX) set and the process's "
206 "effective user ID is neither the user ID of the file to be deleted nor that of the "
207 "directory containing it, and the process is not privileged (Linux: does not have the "
208 "CAP_FOWNER capability).");
210 return makeFailed(
"Path " + path.
native() +
" refers to a directory on a read-only file system.");
222 std::ifstream ifs(from.
native().c_str());
230 std::ofstream ofs(to.
native());
237 ifs.read(&buffer[0], buffer.
size());
238 ofs.write(&buffer[0], ifs.gcount());
240 return makeFailed(
"Failed from copy the file");
257 result =
copyFile(from / path, to / path);
259 case PathType::DIRECTORY:
275 chdir(path.
native().c_str());
278 FileSystem::DirectoryIterator::DirectoryIterator(DIR* dir)
291 entry = readdir(dir);
292 }
while (entry && (**
this ==
Path(
".") || **
this ==
Path(
"..")));
298 return Path(entry->d_name);
302 return (!entry && !other.entry) || entry == other.entry;
307 return (entry || other.entry) && entry != other.entry;
316 dir = opendir(directory.
native().c_str());
351 handle = open(path.
native().c_str(), O_RDONLY);
352 TODO(
"check that the file exists and was correctly opened");
356 flock(handle, LOCK_EX | LOCK_NB);
360 flock(handle, LOCK_UN | LOCK_NB);
#define SPH_ASSERT(x,...)
#define NOT_IMPLEMENTED
Helper macro marking missing implementation.
uint32_t Size
Integral type used to index arrays (by default).
#define NAMESPACE_SPH_END
const SuccessTag SUCCESS
Global constant for successful outcome.
INLINE Outcome makeFailed(TArgs &&... args)
Constructs failed object with error message.
Generic dynamically allocated resizable storage.
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
Wrapper of type that either contains a value of given type, or an error message.
const Error & error() const
Returns the error message.
Type & value()
Returns the reference to expected value.
Object providing begin and end directory iterator for given directory path.
DirectoryIterator begin() const
Returns the directory iterator to the first entry in the directory.
DirectoryIterator end() const
Returns the directory iterator to the one-past-last entry in the directory.
DirectoryAdapter(const Path &directory)
Creates the directory adapter for given path.
Iterator allowing to enumerate files and subdirectories in given directory.
Path operator*() const
Return the path of the file. The path is returned relative to the parent directory.
DirectoryIterator & operator++()
Moves to the next file in the directory.
bool operator==(const DirectoryIterator &other) const
Checks for equality. Returns true in case both iterators are nullptr.
bool operator!=(const DirectoryIterator &other) const
Checks for inequality. Returns false in case both iterators are nullptr.
FileLock(const Path &path)
Wrapper of an integral value providing functions for reading and modifying individual bits.
constexpr INLINE bool has(const TEnum flag) const
Checks if the object has a given flag.
Object representing a path on a filesystem.
std::string native() const
Returns the native version of the path.
bool isRoot() const
Checks if the object holds root path.
bool empty() const
Checks if the path is empty.
Path parentPath() const
Returns the parent directory. If the path is empty or root, return empty path.
Array with fixed number of allocated elements.
INLINE TCounter size() const
Returns the current size of the array (number of constructed elements).
bool isPathWritable(const Path &path)
Checks whether the given file is writable.
bool pathExists(const Path &path)
Checks if a file or directory exists (or more precisely, if a file or directory is accessible).
bool isFileLocked(const Path &path)
void setWorkingDirectory(const Path &path)
Changes the current working directory.
Outcome removePath(const Path &path, const Flags< RemovePathFlag > flags=EMPTY_FLAGS)
Array< Path > getFilesInDirectory(const Path &directory)
Alternatitve to iterateDirectory, returning all files in directory in an array.
Outcome copyDirectory(const Path &from, const Path &to)
Copies a directory (and all files and subdirectories it contains) to a different path.
@ ALLOW_EXISTING
If the named directory already exists, function returns SUCCESS instead of error message.
Size fileSize(const Path &path)
Returns the size of a file.
Outcome createDirectory(const Path &path, const Flags< CreateDirectoryFlag > flags=CreateDirectoryFlag::ALLOW_EXISTING)
Creates a directory with given path. Creates all parent directories as well.
Outcome copyFile(const Path &from, const Path &to)
Copies a file on given path to a different path.
DirectoryAdapter iterateDirectory(const Path &directory)
Expected< PathType > pathType(const Path &path)
Returns the type of the given path, or error message if the function fails.
std::string readFile(const Path &path)
Reads the whole file into the string.
Expected< Path > getHomeDirectory()
Returns the home directory of the current user.
Path getAbsolutePath(const Path &relativePath)
Returns the absolute path to the file.