236 lines
6.0 KiB
C++
236 lines
6.0 KiB
C++
|
/***
|
||
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||
|
|
||
|
File: FS.Unix.cpp
|
||
|
Date: 2021-6-12
|
||
|
Author: Reece
|
||
|
***/
|
||
|
#include <RuntimeInternal.hpp>
|
||
|
#include "FS.hpp"
|
||
|
#include "FS.Generic.hpp"
|
||
|
#include <Time/Time.hpp>
|
||
|
|
||
|
#if !defined(_AURUNTIME_GENERICFS)
|
||
|
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/stat.h>
|
||
|
|
||
|
namespace Aurora::IO::FS
|
||
|
{
|
||
|
bool _MkDir(const AuString &str)
|
||
|
{
|
||
|
return mkdir(path.c_str(), 0760) == 0;
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool FilesInDirectory(const AuString &string, AuList<AuString> &files)
|
||
|
{
|
||
|
return IterateDirEntriesSTL(string, true, files);
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool DirsInDirectory(const AuString &string, AuList<AuString> &dirs)
|
||
|
{
|
||
|
return IterateDirEntriesSTL(string, false, dirs);
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool WriteFile(const AuString &path, const void *data, size_t length)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
auto normalizedPath = RetPathHelper(cpath);
|
||
|
|
||
|
std::ofstream file;
|
||
|
bool ret = false;
|
||
|
|
||
|
CreateDirectories(normalizedPath, true);
|
||
|
|
||
|
#if defined(NO_STD_FS)
|
||
|
file.open(normalizedPath, std::ofstream::binary | std::ofstream::trunc);
|
||
|
#else
|
||
|
file.open(std::filesystem::u8path(normalizedPath), std::ofstream::binary | std::ofstream::trunc);
|
||
|
#endif
|
||
|
|
||
|
if (!file.is_open())
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (file.write(reinterpret_cast<const char *>(data), length))
|
||
|
{
|
||
|
ret = true;
|
||
|
}
|
||
|
|
||
|
file.close();
|
||
|
return ret;
|
||
|
}
|
||
|
catch (...)
|
||
|
{
|
||
|
LogWarn("Unexpected error during IO operation ({})", cpath);
|
||
|
Debugging::PrintError();
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool WriteString(const AuString &path, const AuString &str)
|
||
|
{
|
||
|
return WriteFile(path, str.c_str(), str.size());
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool ReadFile(const AuString &path, AuList<uint8_t> &buffer)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
#if defined(NO_STD_FS)
|
||
|
std::ifstream file(RetPathHelper(cpath), std::ios::binary | std::ios::ate);
|
||
|
#else
|
||
|
std::ifstream file(std::filesystem::u8path(RetPathHelper(cpath)), std::ios::binary | std::ios::ate);
|
||
|
#endif
|
||
|
|
||
|
if (!file.is_open())
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
auto len = static_cast<size_t>(file.tellg());
|
||
|
buffer.resize(len);
|
||
|
|
||
|
file.seekg(0, std::ios::beg);
|
||
|
file.read(reinterpret_cast<char *>(buffer.data()), buffer.size());
|
||
|
file.close();
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
catch (...)
|
||
|
{
|
||
|
LogWarn("Unexpected error during IO operation ({})", cpath);
|
||
|
Debugging::PrintError();
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool ReadString(const AuString &path, AuString &buffer)
|
||
|
{
|
||
|
AuList<uint8_t> buf;
|
||
|
|
||
|
if (!ReadFile(path, buf))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
buffer = AuString(buf.begin(), buf.end());
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
static bool UnixExists(const AuString &path, bool dir)
|
||
|
{
|
||
|
struct stat s;
|
||
|
int err = stat(path.c_str(), &s);
|
||
|
if (-1 == err)
|
||
|
{
|
||
|
SysAssert(ENOENT == errno, "General File IO Error, path {}", path);
|
||
|
return false;
|
||
|
}
|
||
|
return dir ? S_ISDIR(s.st_mode) : S_ISREG(s.st_mode);
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool FileExists(const AuString &path)
|
||
|
{
|
||
|
return UnixExists(NormalizePathRet(path), false);
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool DirExists(const AuString &path)
|
||
|
{
|
||
|
return UnixExists(NormalizePathRet(path), true);
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool DirMk(const AuString &path)
|
||
|
{
|
||
|
return CreateDirectories(NormalizePathRet(path), false);
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool Remove(const AuString &path)
|
||
|
{
|
||
|
return remove(RetPathHelper(path).c_str()) != -1;
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool Relink(const AuString &src, const AuString &dest)
|
||
|
{
|
||
|
return rename(NormalizePathRet(src).c_str(), NormalizePathRet(dest).c_str()) != -1;
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool Copy(const AuString &src, const AuString &dest)
|
||
|
{
|
||
|
auto normalizedSrcPath = NormalizePathRet(src);
|
||
|
auto normalizedDestPath = NormalizePathRet(dest);
|
||
|
|
||
|
int input, output;
|
||
|
|
||
|
if ((input = open(normalizedSrcPath.c_str(), O_RDONLY)) == -1)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
struct stat fileinfo = { 0 };
|
||
|
if (fstat(input, &fileinfo) != 0)
|
||
|
{
|
||
|
close(input)
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if ((output = creat(normalizedDestPath.c_str(), fileinfo.st_mode)) == -1)
|
||
|
{
|
||
|
close(input);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
off_t bytesCopied = 0;
|
||
|
auto result = sendfile(output, input, &bytesCopied, fileinfo.st_size) != -1;
|
||
|
|
||
|
close(input);
|
||
|
close(output);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool StatFile(const AuString &pathRel, Stat &stat)
|
||
|
{
|
||
|
stat = {};
|
||
|
auto path = NormalizePathRet(pathRel);
|
||
|
|
||
|
struct stat s;
|
||
|
auto err = stat(path.c_str(), &s);
|
||
|
|
||
|
if (err == -1)
|
||
|
{
|
||
|
if (ENOENT == errno)
|
||
|
{
|
||
|
LogWarn("Critical IO error, errno = {}", path);
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
stat.existsFile = S_ISREG(s.st_mode);
|
||
|
stat.existsDirectory = S_ISDIR(s.st_mode);
|
||
|
stat.existsSystemResource = S_ISSOCK(s.st_mode);
|
||
|
stat.exists = stat.existsFile || stat.existsDirectory || stat.existsSystemResource;
|
||
|
|
||
|
if (!stat.exists)
|
||
|
{
|
||
|
LogWarn("Missing attribute type of path {}, stat mode {}", path, s.st_mode);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
stat.size = s.st_size;
|
||
|
|
||
|
stat.created = ConvertUnixTimespecToMs(s.st_ctime);
|
||
|
stat.modified = ConvertUnixTimespecToMs(s.st_mtime);
|
||
|
stat.accessed = ConvertUnixTimespecToMs(s.st_atime);
|
||
|
|
||
|
err = lstat(path.c_str(), &s);
|
||
|
if (err != -1)
|
||
|
{
|
||
|
stat.symLink = S_ISLNK(s.st_mode);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
#endif
|