eden/src/frontend_common/data_manager.cpp
lizzie ee188168c1
Some checks are pending
tx-src / sources (push) Waiting to run
Check Strings / check-strings (push) Waiting to run
[common] do not crash when don't have permissions to /tmp/eden directory due to unforessen circumstances (FreeBSD) (#3912)
instead of throwing, use std::error_code and such

due to reasons unberknownst to me, the UID of the /tmp/eden directory was set for another user, this inevitably caused a crash due to wrong permissions (which is a very user unfriendly thing to do generally)

Signed-off-by: lizzie <lizzie@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3912
Reviewed-by: crueter <crueter@eden-emu.dev>
2026-05-13 19:14:59 +02:00

82 lines
2.5 KiB
C++

// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <filesystem>
#include "data_manager.h"
#include "common/assert.h"
#include "common/fs/path_util.h"
#include <fmt/format.h>
namespace FrontendCommon::DataManager {
namespace fs = std::filesystem;
const fs::path GetDataDir(DataDir dir, const std::string &user_id)
{
const fs::path nand_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir);
const fs::path save_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::SaveDir);
switch (dir) {
case DataDir::Saves:
return (save_dir / "user" / "save" / "0000000000000000" / user_id).string();
case DataDir::UserNand:
return (nand_dir / "user" / "Contents" / "registered").string();
case DataDir::SysNand:
// NB: do NOT delete save
// that contains profile data and other stuff
return (nand_dir / "system" / "Contents" / "registered").string();
case DataDir::Mods:
return Common::FS::GetEdenPathString(Common::FS::EdenPath::LoadDir);
case DataDir::Shaders:
return Common::FS::GetEdenPathString(Common::FS::EdenPath::ShaderDir);
default:
UNIMPLEMENTED();
}
return "";
}
const std::string GetDataDirString(DataDir dir, const std::string &user_id)
{
auto dirString = GetDataDir(dir, user_id).string();
std::filesystem::create_directories(dirString);
return dirString;
}
u64 ClearDir(DataDir dir, const std::string &user_id)
{
fs::path data_dir = GetDataDir(dir, user_id);
std::error_code ec;
u64 result = fs::remove_all(data_dir, ec);
// mkpath at the end just so it actually exists
fs::create_directories(data_dir, ec);
return result;
}
std::string ReadableBytesSize(u64 size) noexcept {
std::array<std::string_view, 6> const units{"B", "KB", "MB", "GB", "TB", "PB"};
u64 const base = 1000;
if (size == 0)
return "0 B";
auto const digit_groups = std::min<u64>(u64(std::log10(size) / std::log10(base)), u64(units.size()));
return fmt::format("{:.1f} {}", size / std::pow(base, digit_groups), units[digit_groups]);
}
u64 DataDirSize(DataDir dir)
{
fs::path data_dir = GetDataDir(dir);
u64 size = 0;
if (!fs::exists(data_dir))
return 0;
for (const auto &entry : fs::recursive_directory_iterator(data_dir)) {
if (!entry.is_directory()) {
size += entry.file_size();
}
}
return size;
}
} // namespace FrontendCommon::DataManager