refactor
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
This commit is contained in:
@ -22,22 +22,13 @@
|
|||||||
#ifndef INCLUDE_UTILS_FILE_UTILS_HPP_
|
#ifndef INCLUDE_UTILS_FILE_UTILS_HPP_
|
||||||
#define INCLUDE_UTILS_FILE_UTILS_HPP_
|
#define INCLUDE_UTILS_FILE_UTILS_HPP_
|
||||||
|
|
||||||
#include "types/repertory.hpp"
|
|
||||||
#include "utils/file.hpp"
|
#include "utils/file.hpp"
|
||||||
|
|
||||||
namespace repertory::utils::file {
|
namespace repertory::utils::file {
|
||||||
void change_to_process_directory();
|
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto
|
||||||
get_directory_files(std::string path, bool oldest_first,
|
get_directory_files(std::string_view path, bool oldest_first,
|
||||||
bool recursive = false) -> std::deque<std::string>;
|
bool recursive = false) -> std::deque<std::string>;
|
||||||
|
|
||||||
[[nodiscard]] auto
|
|
||||||
get_free_drive_space(const std::string &path) -> std::uint64_t;
|
|
||||||
|
|
||||||
[[nodiscard]] auto
|
|
||||||
get_total_drive_space(const std::string &path) -> std::uint64_t;
|
|
||||||
|
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto
|
||||||
read_file_lines(const std::string &path) -> std::vector<std::string>;
|
read_file_lines(const std::string &path) -> std::vector<std::string>;
|
||||||
|
|
||||||
|
@ -317,11 +317,12 @@ auto app_config::get_json() const -> json {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto app_config::get_max_cache_size_bytes() const -> std::uint64_t {
|
auto app_config::get_max_cache_size_bytes() const -> std::uint64_t {
|
||||||
const auto max_space =
|
auto max_space =
|
||||||
std::max(static_cast<std::uint64_t>(100ULL * 1024ULL * 1024ULL),
|
std::max(static_cast<std::uint64_t>(100ULL * 1024ULL * 1024ULL),
|
||||||
max_cache_size_bytes_);
|
max_cache_size_bytes_);
|
||||||
return std::min(utils::file::get_free_drive_space(get_cache_directory()),
|
auto free_space = utils::file::get_free_drive_space(get_cache_directory());
|
||||||
max_space);
|
return free_space.has_value() ? std::min(free_space.value(), max_space)
|
||||||
|
: max_space;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto app_config::get_provider_display_name(const provider_type &prov)
|
auto app_config::get_provider_display_name(const provider_type &prov)
|
||||||
|
@ -393,31 +393,34 @@ auto fuse_base::init_(struct fuse_conn_info *conn) -> void * {
|
|||||||
#if FUSE_USE_VERSION >= 30
|
#if FUSE_USE_VERSION >= 30
|
||||||
auto fuse_base::init_impl([[maybe_unused]] struct fuse_conn_info *conn,
|
auto fuse_base::init_impl([[maybe_unused]] struct fuse_conn_info *conn,
|
||||||
struct fuse_config *cfg) -> void * {
|
struct fuse_config *cfg) -> void * {
|
||||||
#else
|
#else // FUSE_USE_VERSION < 30
|
||||||
auto fuse_base::init_impl(struct fuse_conn_info *conn) -> void * {
|
auto fuse_base::init_impl(struct fuse_conn_info *conn) -> void * {
|
||||||
#endif
|
#endif // FUSE_USE_VERSION >= 30
|
||||||
static constexpr const std::string_view function_name{
|
static constexpr const std::string_view function_name{
|
||||||
static_cast<const char *>(__FUNCTION__),
|
static_cast<const char *>(__FUNCTION__),
|
||||||
};
|
};
|
||||||
|
|
||||||
utils::file::change_to_process_directory();
|
|
||||||
if (not console_enabled_) {
|
|
||||||
if (not repertory::project_initialize()) {
|
|
||||||
utils::error::raise_error(function_name,
|
|
||||||
"failed to initialize repertory");
|
|
||||||
event_system::instance().raise<unmount_requested>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
conn->want |= FUSE_CAP_VOL_RENAME;
|
conn->want |= FUSE_CAP_VOL_RENAME;
|
||||||
conn->want |= FUSE_CAP_XTIMES;
|
conn->want |= FUSE_CAP_XTIMES;
|
||||||
#endif // __APPLE__
|
#endif // defined(__APPLE__)
|
||||||
|
|
||||||
#if FUSE_USE_VERSION >= 30
|
#if FUSE_USE_VERSION >= 30
|
||||||
cfg->nullpath_ok = 0;
|
cfg->nullpath_ok = 0;
|
||||||
cfg->hard_remove = 1;
|
cfg->hard_remove = 1;
|
||||||
#endif
|
#endif // FUSE_USE_VERSION >= 30
|
||||||
|
|
||||||
|
if (not utils::file::change_to_process_directory()) {
|
||||||
|
utils::error::raise_error(function_name,
|
||||||
|
"failed to change to process directory");
|
||||||
|
event_system::instance().raise<unmount_requested>();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not console_enabled_ && not repertory::project_initialize()) {
|
||||||
|
utils::error::raise_error(function_name, "failed to initialize repertory");
|
||||||
|
event_system::instance().raise<unmount_requested>();
|
||||||
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -623,7 +623,9 @@ auto winfsp_drive::Mounted(PVOID host) -> NTSTATUS {
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto ret = STATUS_SUCCESS;
|
auto ret = STATUS_SUCCESS;
|
||||||
utils::file::change_to_process_directory();
|
if (not utils::file::change_to_process_directory()) {
|
||||||
|
return utils::get_last_error_code();
|
||||||
|
}
|
||||||
|
|
||||||
auto *file_system_host = reinterpret_cast<FileSystemHost *>(host);
|
auto *file_system_host = reinterpret_cast<FileSystemHost *>(host);
|
||||||
polling::instance().start(&config_);
|
polling::instance().start(&config_);
|
||||||
|
@ -628,8 +628,9 @@ auto encrypt_provider::get_item_meta(const std::string &api_path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto encrypt_provider::get_total_drive_space() const -> std::uint64_t {
|
auto encrypt_provider::get_total_drive_space() const -> std::uint64_t {
|
||||||
const auto cfg = config_.get_encrypt_config();
|
auto total_space =
|
||||||
return utils::file::get_total_drive_space(cfg.path);
|
utils::file::get_total_drive_space(config_.get_encrypt_config().path);
|
||||||
|
return total_space.value_or(0U);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto encrypt_provider::get_total_item_count() const -> std::uint64_t {
|
auto encrypt_provider::get_total_item_count() const -> std::uint64_t {
|
||||||
@ -646,8 +647,10 @@ auto encrypt_provider::get_total_item_count() const -> std::uint64_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto encrypt_provider::get_used_drive_space() const -> std::uint64_t {
|
auto encrypt_provider::get_used_drive_space() const -> std::uint64_t {
|
||||||
const auto cfg = config_.get_encrypt_config();
|
auto free_space =
|
||||||
return get_total_drive_space() - utils::file::get_free_drive_space(cfg.path);
|
utils::file::get_free_drive_space(config_.get_encrypt_config().path);
|
||||||
|
return free_space.has_value() ? get_total_drive_space() - free_space.value()
|
||||||
|
: 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto encrypt_provider::is_directory(const std::string &api_path,
|
auto encrypt_provider::is_directory(const std::string &api_path,
|
||||||
|
@ -31,121 +31,70 @@
|
|||||||
#include "utils/utils.hpp"
|
#include "utils/utils.hpp"
|
||||||
|
|
||||||
namespace repertory::utils::file {
|
namespace repertory::utils::file {
|
||||||
void change_to_process_directory() {
|
auto get_directory_files(std::string_view path, bool oldest_first,
|
||||||
#if defined(_WIN32)
|
|
||||||
std::string file_name;
|
|
||||||
file_name.resize(MAX_PATH);
|
|
||||||
::GetModuleFileNameA(nullptr, &file_name[0U],
|
|
||||||
static_cast<DWORD>(file_name.size()));
|
|
||||||
|
|
||||||
std::string path = file_name.c_str();
|
|
||||||
::PathRemoveFileSpecA(&path[0U]);
|
|
||||||
::SetCurrentDirectoryA(&path[0U]);
|
|
||||||
#else
|
|
||||||
std::string path;
|
|
||||||
path.resize(PATH_MAX + 1);
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
proc_pidpath(getpid(), &path[0U], path.size());
|
|
||||||
#else
|
|
||||||
readlink("/proc/self/exe", &path[0U], path.size());
|
|
||||||
#endif
|
|
||||||
path = utils::path::get_parent_path(path);
|
|
||||||
chdir(path.c_str());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
auto get_free_drive_space(const std::string &path) -> std::uint64_t {
|
|
||||||
#if defined(_WIN32)
|
|
||||||
ULARGE_INTEGER li{};
|
|
||||||
::GetDiskFreeSpaceEx(path.c_str(), &li, nullptr, nullptr);
|
|
||||||
return li.QuadPart;
|
|
||||||
#endif
|
|
||||||
#if defined(__linux__)
|
|
||||||
std::uint64_t ret = 0;
|
|
||||||
struct statfs64 st {};
|
|
||||||
if (statfs64(path.c_str(), &st) == 0) {
|
|
||||||
ret = st.f_bfree * st.f_bsize;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
#endif
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
struct statvfs st {};
|
|
||||||
statvfs(path.c_str(), &st);
|
|
||||||
return st.f_bfree * st.f_frsize;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
auto get_total_drive_space(const std::string &path) -> std::uint64_t {
|
|
||||||
#if defined(_WIN32)
|
|
||||||
ULARGE_INTEGER li{};
|
|
||||||
::GetDiskFreeSpaceEx(path.c_str(), nullptr, &li, nullptr);
|
|
||||||
return li.QuadPart;
|
|
||||||
#endif
|
|
||||||
#if defined(__linux__)
|
|
||||||
std::uint64_t ret = 0;
|
|
||||||
struct statfs64 st {};
|
|
||||||
if (statfs64(path.c_str(), &st) == 0) {
|
|
||||||
ret = st.f_blocks * st.f_bsize;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
#endif
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
struct statvfs st {};
|
|
||||||
statvfs(path.c_str(), &st);
|
|
||||||
return st.f_blocks * st.f_frsize;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
auto get_directory_files(std::string path, bool oldest_first,
|
|
||||||
bool recursive) -> std::deque<std::string> {
|
bool recursive) -> std::deque<std::string> {
|
||||||
path = utils::path::absolute(path);
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
auto abs_path = utils::path::absolute(path);
|
||||||
std::deque<std::string> ret;
|
std::deque<std::string> ret;
|
||||||
std::unordered_map<std::string, std::uint64_t> lookup;
|
std::unordered_map<std::string, std::uint64_t> lookup;
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
WIN32_FIND_DATA fd{};
|
WIN32_FIND_DATA fd{};
|
||||||
const auto search = utils::path::combine(path, {"*.*"});
|
auto search = utils::path::combine(abs_path, {"*.*"});
|
||||||
auto find = ::FindFirstFile(search.c_str(), &fd);
|
auto find = ::FindFirstFile(search.c_str(), &fd);
|
||||||
if (find != INVALID_HANDLE_VALUE) {
|
if (find != INVALID_HANDLE_VALUE) {
|
||||||
do {
|
try {
|
||||||
const auto full_path = utils::path::combine(path, {fd.cFileName});
|
do {
|
||||||
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==
|
auto full_path = utils::path::combine(abs_path, {fd.cFileName});
|
||||||
FILE_ATTRIBUTE_DIRECTORY) {
|
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==
|
||||||
if (recursive) {
|
FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
const auto sub_files =
|
if (recursive) {
|
||||||
get_directory_files(full_path, oldest_first, recursive);
|
auto sub_files =
|
||||||
ret.insert(ret.end(), sub_files.begin(), sub_files.end());
|
get_directory_files(full_path, oldest_first, recursive);
|
||||||
} else {
|
ret.insert(ret.end(), sub_files.begin(), sub_files.end());
|
||||||
ULARGE_INTEGER li{};
|
} else {
|
||||||
li.HighPart = fd.ftLastWriteTime.dwHighDateTime;
|
ULARGE_INTEGER li{};
|
||||||
li.LowPart = fd.ftLastWriteTime.dwLowDateTime;
|
li.HighPart = fd.ftLastWriteTime.dwHighDateTime;
|
||||||
lookup[full_path] = li.QuadPart;
|
li.LowPart = fd.ftLastWriteTime.dwLowDateTime;
|
||||||
ret.emplace_back(full_path);
|
lookup[full_path] = li.QuadPart;
|
||||||
|
ret.emplace_back(full_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} while (::FindNextFile(find, &fd) != 0);
|
||||||
} while (::FindNextFile(find, &fd) != 0);
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::raise_error(function_name, e,
|
||||||
|
"failed to get directory files");
|
||||||
|
}
|
||||||
::FindClose(find);
|
::FindClose(find);
|
||||||
|
|
||||||
std::sort(ret.begin(), ret.end(),
|
std::sort(ret.begin(), ret.end(), [&](auto &&path1, auto &&path2) -> bool {
|
||||||
[&](const auto &p1, const auto &p2) -> bool {
|
return (oldest_first != 0) == (lookup[path1] < lookup[path2]);
|
||||||
return (oldest_first != 0) == (lookup[p1] < lookup[p2]);
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
#else
|
#else // !defined(_WIN32)
|
||||||
auto *root = opendir(path.c_str());
|
auto *root = opendir(abs_path.c_str());
|
||||||
if (root) {
|
if (root) {
|
||||||
struct dirent *de{};
|
try {
|
||||||
while ((de = readdir(root)) != nullptr) {
|
struct dirent *de{};
|
||||||
if (de->d_type == DT_DIR) {
|
while ((de = readdir(root)) != nullptr) {
|
||||||
if (recursive) {
|
if (de->d_type == DT_DIR) {
|
||||||
const auto sub_files =
|
if (recursive) {
|
||||||
get_directory_files(utils::path::combine(path, {de->d_name}),
|
auto sub_files = get_directory_files(
|
||||||
oldest_first, recursive);
|
utils::path::combine(abs_path, {de->d_name}), oldest_first,
|
||||||
ret.insert(ret.end(), sub_files.begin(), sub_files.end());
|
recursive);
|
||||||
|
ret.insert(ret.end(), sub_files.begin(), sub_files.end());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret.emplace_back(utils::path::combine(abs_path, {de->d_name}));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ret.emplace_back(utils::path::combine(path, {de->d_name}));
|
|
||||||
}
|
}
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::raise_error(function_name, e,
|
||||||
|
"failed to get directory files");
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(root);
|
closedir(root);
|
||||||
|
|
||||||
const auto add_to_lookup = [&](const std::string &lookup_path) {
|
const auto add_to_lookup = [&](const std::string &lookup_path) {
|
||||||
@ -153,25 +102,26 @@ auto get_directory_files(std::string path, bool oldest_first,
|
|||||||
struct stat st {};
|
struct stat st {};
|
||||||
stat(lookup_path.c_str(), &st);
|
stat(lookup_path.c_str(), &st);
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
lookup[lookup_path] = static_cast<std::uint64_t>(
|
lookup[lookup_path] =
|
||||||
(st.st_mtimespec.tv_sec * utils::time::NANOS_PER_SECOND) +
|
(static_cast<std::uint64_t>(st.st_mtimespec.tv_sec) *
|
||||||
st.st_mtimespec.tv_nsec);
|
utils::time::NANOS_PER_SECOND) +
|
||||||
|
static_cast<std::uint64_t>(st.st_mtimespec.tv_nsec);
|
||||||
#else // !defined(__APPLE__)
|
#else // !defined(__APPLE__)
|
||||||
lookup[lookup_path] = static_cast<std::uint64_t>(
|
lookup[lookup_path] = (static_cast<std::uint64_t>(st.st_mtim.tv_sec) *
|
||||||
(st.st_mtim.tv_sec * utils::time::NANOS_PER_SECOND) +
|
utils::time::NANOS_PER_SECOND) +
|
||||||
st.st_mtim.tv_nsec);
|
static_cast<std::uint64_t>(st.st_mtim.tv_nsec);
|
||||||
#endif // defined(__APPLE__)
|
#endif // defined(__APPLE__)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::sort(ret.begin(), ret.end(),
|
std::sort(ret.begin(), ret.end(), [&](auto &&path1, auto &&path2) -> bool {
|
||||||
[&](const auto &p1, const auto &p2) -> bool {
|
add_to_lookup(path1);
|
||||||
add_to_lookup(p1);
|
add_to_lookup(path2);
|
||||||
add_to_lookup(p2);
|
return (oldest_first != 0) == (lookup.at(path1) < lookup.at(path2));
|
||||||
return (oldest_first != 0) == (lookup[p1] < lookup[p2]);
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +140,7 @@ auto read_file_lines(const std::string &path) -> std::vector<std::string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto reset_modified_time(const std::string &path) -> bool {
|
auto reset_modified_time(const std::string &path) -> bool {
|
||||||
auto ret = false;
|
auto ret{false};
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
SYSTEMTIME st{};
|
SYSTEMTIME st{};
|
||||||
::GetSystemTime(&st);
|
::GetSystemTime(&st);
|
||||||
@ -206,13 +156,14 @@ auto reset_modified_time(const std::string &path) -> bool {
|
|||||||
::CloseHandle(handle);
|
::CloseHandle(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else // !defined(_WIN32)
|
||||||
auto fd = open(path.c_str(), O_RDWR);
|
auto fd = open(path.c_str(), O_RDWR);
|
||||||
if ((ret = (fd != -1))) {
|
if ((ret = (fd != -1))) {
|
||||||
ret = not futimens(fd, nullptr);
|
ret = futimens(fd, nullptr) == 0;
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
#endif
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} // namespace repertory::utils::file
|
} // namespace repertory::utils::file
|
||||||
|
@ -56,6 +56,8 @@ struct file_times final {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] auto change_to_process_directory() -> bool;
|
||||||
|
|
||||||
[[nodiscard]] inline auto
|
[[nodiscard]] inline auto
|
||||||
directory_exists_in_path(std::string_view path,
|
directory_exists_in_path(std::string_view path,
|
||||||
std::string_view sub_directory) -> bool;
|
std::string_view sub_directory) -> bool;
|
||||||
@ -71,6 +73,9 @@ file_exists_in_path(std::string_view path, std::string_view file_name) -> bool;
|
|||||||
file_exists_in_path(std::wstring_view path,
|
file_exists_in_path(std::wstring_view path,
|
||||||
std::wstring_view file_name) -> bool;
|
std::wstring_view file_name) -> bool;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
get_free_drive_space(std::string_view path) -> std::optional<std::uint64_t>;
|
||||||
|
|
||||||
[[nodiscard]] auto get_time(std::string_view path,
|
[[nodiscard]] auto get_time(std::string_view path,
|
||||||
time_type type) -> std::optional<std::uint64_t>;
|
time_type type) -> std::optional<std::uint64_t>;
|
||||||
|
|
||||||
@ -83,6 +88,9 @@ get_times(std::string_view path) -> std::optional<file_times>;
|
|||||||
[[nodiscard]] auto
|
[[nodiscard]] auto
|
||||||
get_times(std::wstring_view path) -> std::optional<file_times>;
|
get_times(std::wstring_view path) -> std::optional<file_times>;
|
||||||
|
|
||||||
|
[[nodiscard]] auto
|
||||||
|
get_total_drive_space(std::string_view path) -> std::optional<std::uint64_t>;
|
||||||
|
|
||||||
#if defined(PROJECT_ENABLE_LIBDSM)
|
#if defined(PROJECT_ENABLE_LIBDSM)
|
||||||
[[nodiscard]] auto
|
[[nodiscard]] auto
|
||||||
smb_create_and_validate_relative_path(std::string_view smb_path,
|
smb_create_and_validate_relative_path(std::string_view smb_path,
|
||||||
|
@ -26,9 +26,102 @@
|
|||||||
#include "utils/path.hpp"
|
#include "utils/path.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
#include "utils/time.hpp"
|
#include "utils/time.hpp"
|
||||||
|
#include "utils/unix.hpp"
|
||||||
#include "utils/windows.hpp"
|
#include "utils/windows.hpp"
|
||||||
|
|
||||||
namespace repertory::utils::file {
|
namespace repertory::utils::file {
|
||||||
|
auto change_to_process_directory() -> bool {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
#if defined(_WIN32)
|
||||||
|
std::string file_name;
|
||||||
|
file_name.resize(MAX_PATH + 1U);
|
||||||
|
|
||||||
|
::GetModuleFileNameA(nullptr, file_name.data(),
|
||||||
|
static_cast<DWORD>(file_name.size() - 1U));
|
||||||
|
auto path = utils::path::strip_to_file_name(file_name.c_str());
|
||||||
|
::SetCurrentDirectoryA(path.c_str());
|
||||||
|
#else // !defined(_WIN32)
|
||||||
|
std::string path;
|
||||||
|
path.resize(PATH_MAX + 1);
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
proc_pidpath(getpid(), path.c_str(), path.size());
|
||||||
|
#else // !defined(__APPLE__)
|
||||||
|
auto res = readlink("/proc/self/exe", path.data(), path.size());
|
||||||
|
if (res == -1) {
|
||||||
|
throw std::runtime_error("failed to readlink|" + path + '|' +
|
||||||
|
std::to_string(errno));
|
||||||
|
}
|
||||||
|
#endif // defined(__APPLE__)
|
||||||
|
path = utils::path::get_parent_path(path);
|
||||||
|
res = chdir(path.c_str());
|
||||||
|
if (res != 0) {
|
||||||
|
throw std::runtime_error("failed to chdir|" + path + '|' +
|
||||||
|
std::to_string(errno));
|
||||||
|
}
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto get_free_drive_space(std::string_view path)
|
||||||
|
-> std::optional<std::uint64_t> {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
#if defined(_WIN32)
|
||||||
|
ULARGE_INTEGER li{};
|
||||||
|
if (not ::GetDiskFreeSpaceEx(path.c_str(), &li, nullptr, nullptr)) {
|
||||||
|
throw std::runtime_error("failed to get free disk space|" +
|
||||||
|
std::string{path} + '|' +
|
||||||
|
std::to_string(utils::get_last_error_code()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return li.QuadPart;
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
|
struct statfs64 st {};
|
||||||
|
if (statfs64(std::string{path}.c_str(), &st) != 0) {
|
||||||
|
throw std::runtime_error("failed to get free disk space|" +
|
||||||
|
std::string{path} + '|' +
|
||||||
|
std::to_string(utils::get_last_error_code()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return st.f_bfree * static_cast<std::uint64_t>(st.f_bsize);
|
||||||
|
#endif // defined(__linux__)
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
struct statvfs st {};
|
||||||
|
if (statvfs(path.c_str(), &st) != 0) {
|
||||||
|
throw std::runtime_error("failed to get free disk space|" +
|
||||||
|
std::string{path} + '|' +
|
||||||
|
std::to_string(utils::get_last_error_code()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return st.f_bfree * static_cast<std::uint64_t>(st.f_frsize);
|
||||||
|
#endif // defined(__APPLE__)
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
auto get_time(std::string_view path,
|
auto get_time(std::string_view path,
|
||||||
time_type type) -> std::optional<std::uint64_t> {
|
time_type type) -> std::optional<std::uint64_t> {
|
||||||
auto times = get_times(path);
|
auto times = get_times(path);
|
||||||
@ -111,6 +204,53 @@ auto get_times(std::wstring_view path) -> std::optional<file_times> {
|
|||||||
return get_times(utils::string::to_utf8(path));
|
return get_times(utils::string::to_utf8(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto get_total_drive_space(std::string_view path)
|
||||||
|
-> std::optional<std::uint64_t> {
|
||||||
|
static constexpr const std::string_view function_name{
|
||||||
|
static_cast<const char *>(__FUNCTION__),
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
#if defined(_WIN32)
|
||||||
|
ULARGE_INTEGER li{};
|
||||||
|
if (not ::GetDiskFreeSpaceEx(path.c_str(), nullptr, &li, nullptr)) {
|
||||||
|
throw std::runtime_error("failed to get total disk space|" +
|
||||||
|
std::string{path} + '|' +
|
||||||
|
std::to_string(utils::get_last_error_code()));
|
||||||
|
}
|
||||||
|
return li.QuadPart;
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
|
struct statfs64 st {};
|
||||||
|
if (statfs64(std::string{path}.c_str(), &st) != 0) {
|
||||||
|
throw std::runtime_error("failed to get total disk space|" +
|
||||||
|
std::string{path} + '|' +
|
||||||
|
std::to_string(utils::get_last_error_code()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return st.f_blocks * static_cast<std::uint64_t>(st.f_bsize);
|
||||||
|
#endif // defined(__linux__)
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
struct statvfs st {};
|
||||||
|
if (statvfs(path.c_str(), &st) != 0) {
|
||||||
|
throw std::runtime_error("failed to get total disk space|" +
|
||||||
|
std::string{path} + '|' +
|
||||||
|
std::to_string(utils::get_last_error_code()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return st.f_blocks * static_cast<std::uint64_t>(st.f_frsize);
|
||||||
|
#endif // defined(__APPLE__)
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
utils::error::handle_exception(function_name, e);
|
||||||
|
} catch (...) {
|
||||||
|
utils::error::handle_exception(function_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
auto i_fs_item::get_time(time_type type) const -> std::optional<std::uint64_t> {
|
auto i_fs_item::get_time(time_type type) const -> std::optional<std::uint64_t> {
|
||||||
return utils::file::get_time(get_path(), type);
|
return utils::file::get_time(get_path(), type);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user