Archived
1
Fork 0
This repository has been archived on 2025-04-12. You can view files and clone it, but cannot push or open issues or pull requests.
graphite/engine/platform/unix/filesystem.cpp

113 lines
2.5 KiB
C++
Raw Normal View History

2024-01-03 16:05:02 -05:00
#include "filesystem.hpp"
#include <sys/sendfile.h>
#include <fcntl.h>
#include <fts.h>
#include <dirent.h>
#include <sys/stat.h>
#include <zconf.h>
#include <unistd.h>
void Filesystem::CreateDirectory(const std::string& path)
{
mkdir(path.c_str(), 0755);
}
void Filesystem::CopyFile(const std::string& src, const std::string& dst, bool overwrite)
{
int read_fd;
int write_fd;
struct stat stat_buf;
off_t offset = 0;
read_fd = open(src.c_str(), O_RDONLY);
fstat (read_fd, &stat_buf);
int wflags = O_WRONLY | O_CREAT;
if(overwrite)
wflags |= O_TRUNC;
write_fd = open(dst.c_str(), wflags, stat_buf.st_mode);
sendfile(write_fd, read_fd, &offset, stat_buf.st_size);
close(read_fd);
close(write_fd);
}
void Filesystem::CopyDirectory(const std::string& src, const std::string& dst, bool overwrite)
{
CreateDirectory(dst);
char* paths[] = { const_cast<char*>(src.c_str()), 0 };
FTS* tree = fts_open(paths, FTS_NOCHDIR, 0);
FTSENT *node;
while ((node = fts_read(tree)))
{
if(node->fts_level > 0 && node->fts_name[0] == '.')
{
fts_set(tree, node, FTS_SKIP);
}
else if(node->fts_info & FTS_F)
{
CopyFile(node->fts_path, dst + Utility::RemoveSubstrings(node->fts_path, { src }), overwrite);
}
else if(node->fts_info & FTS_D)
{
CreateDirectory(dst + Utility::RemoveSubstrings(node->fts_path, { src }));
}
}
fts_close(tree);
}
void Filesystem::Remove(const std::string& path)
{
unlink(path.c_str());
}
std::string Filesystem::Canonical(const std::string& path)
{
char* n = new char[PATH_MAX];
realpath(path.c_str(), n);
return n;
}
std::vector<std::string> Filesystem::DirectoryContents(const std::string& directory)
{
std::vector<std::string> tmp;
char* paths[] = { const_cast<char*>(directory.c_str()), 0 };
FTS* tree = fts_open(paths, FTS_NOCHDIR, 0);
FTSENT *node;
while ((node = fts_read(tree)))
{
if(node->fts_level > 0 && node->fts_name[0] == '.')
{
fts_set(tree, node, FTS_SKIP);
}
else if(node->fts_info & FTS_F)
{
tmp.push_back(std::string(node->fts_accpath));
}
}
fts_close(tree);
return tmp;
}
bool Filesystem::DirectoryExists(const std::string& path)
{
DIR* dir = opendir(path.c_str());
return dir != nullptr;
}
bool Filesystem::FileExists(const std::string& path)
{
return access(path.c_str(), F_OK) != -1;
}