ams: support building unit test programs on windows/linux/macos

This commit is contained in:
Michael Scire
2022-03-06 12:08:20 -08:00
committed by SciresM
parent 9a38be201a
commit 64a97576d0
756 changed files with 33359 additions and 9372 deletions

View File

@@ -24,7 +24,7 @@ namespace ams::fs::impl {
template<typename List, typename Iter>
void Remove(List &list, Iter *desired) {
for (auto it = list.cbegin(); it != list.cend(); it++) {
for (auto it = list.cbegin(); it != list.cend(); ++it) {
if (it.operator->() == desired) {
list.erase(it);
return;
@@ -35,18 +35,13 @@ namespace ams::fs::impl {
AMS_ABORT();
}
Result ValidatePath(const char *mount_name, const char *path) {
const size_t mount_name_len = strnlen(mount_name, MountNameLengthMax);
const size_t path_len = strnlen(path, EntryNameLengthMax);
R_UNLESS(mount_name_len + 1 + path_len <= EntryNameLengthMax, fs::ResultTooLongPath());
return ResultSuccess();
}
Result ValidateMountName(const char *name) {
Result SetMountName(char *dst, const char *name) {
R_UNLESS(name[0] != 0, fs::ResultInvalidMountName());
R_UNLESS(strnlen(name, sizeof(MountName)) < sizeof(MountName), fs::ResultInvalidMountName());
return ResultSuccess();
const size_t n_len = util::Strlcpy<char>(dst, name, MountNameLengthMax + 1);
R_UNLESS(n_len <= MountNameLengthMax, fs::ResultInvalidMountName());
R_SUCCEED();
}
template<typename List>
@@ -54,18 +49,21 @@ namespace ams::fs::impl {
for (auto it = list.cbegin(); it != list.cend(); it++) {
R_UNLESS((it->GetOpenMode() & OpenMode_Write) == 0, fs::ResultWriteModeFileNotClosed());
}
return ResultSuccess();
R_SUCCEED();
}
}
FileSystemAccessor::FileSystemAccessor(const char *n, std::unique_ptr<fsa::IFileSystem> &&fs, std::unique_ptr<fsa::ICommonMountNameGenerator> &&generator)
: m_impl(std::move(fs)), m_open_list_lock(), m_mount_name_generator(std::move(generator)),
m_access_log_enabled(false), m_data_cache_attachable(false), m_path_cache_attachable(false), m_path_cache_attached(false), m_multi_commit_supported(false)
m_access_log_enabled(false), m_data_cache_attachable(false), m_path_cache_attachable(false), m_path_cache_attached(false), m_multi_commit_supported(false),
m_path_flags()
{
R_ABORT_UNLESS(ValidateMountName(n));
std::strncpy(m_name.str, n, MountNameLengthMax);
m_name.str[MountNameLengthMax] = 0;
R_ABORT_UNLESS(SetMountName(m_name.str, n));
if (std::strcmp(m_name.str, AMS_FS_IMPL_HOST_ROOT_FILE_SYSTEM_MOUNT_NAME) == 0) {
m_path_flags.AllowWindowsPath();
}
}
FileSystemAccessor::~FileSystemAccessor() {
@@ -83,13 +81,12 @@ namespace ams::fs::impl {
Result FileSystemAccessor::GetCommonMountName(char *dst, size_t dst_size) const {
R_UNLESS(m_mount_name_generator != nullptr, fs::ResultPreconditionViolation());
return m_mount_name_generator->GenerateCommonMountName(dst, dst_size);
R_RETURN(m_mount_name_generator->GenerateCommonMountName(dst, dst_size));
}
std::shared_ptr<fssrv::impl::FileSystemInterfaceAdapter> FileSystemAccessor::GetMultiCommitTarget() {
if (m_multi_commit_supported) {
/* TODO: Support multi commit. */
AMS_ABORT();
AMS_ABORT("TODO: Support multi commit");
}
return nullptr;
}
@@ -104,71 +101,126 @@ namespace ams::fs::impl {
Remove(m_open_dir_list, d);
}
Result FileSystemAccessor::SetUpPath(fs::Path *out, const char *p) {
/* Initialize the path appropriately. */
bool normalized;
size_t len;
if (R_SUCCEEDED(PathFormatter::IsNormalized(std::addressof(normalized), std::addressof(len), p, m_path_flags)) && normalized) {
/* We can use the input buffer directly. */
out->SetShallowBuffer(p);
} else {
/* Initialize with appropriate slash replacement. */
if (m_path_flags.IsWindowsPathAllowed()) {
R_TRY(out->InitializeWithReplaceForwardSlashes(p));
} else {
R_TRY(out->InitializeWithReplaceBackslash(p));
}
/* Ensure we're normalized. */
R_TRY(out->Normalize(m_path_flags));
}
/* Check the path isn't too long. */
R_UNLESS(out->GetLength() <= fs::EntryNameLengthMax, fs::ResultTooLongPath());
R_SUCCEED();
}
Result FileSystemAccessor::CreateFile(const char *path, s64 size, int option) {
R_TRY(ValidatePath(m_name.str, path));
/* Create path. */
fs::Path normalized_path;
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
if (m_path_cache_attached) {
/* TODO: Path cache */
R_TRY(m_impl->CreateFile(path, size, option));
R_TRY(m_impl->CreateFile(normalized_path, size, option));
} else {
R_TRY(m_impl->CreateFile(path, size, option));
R_TRY(m_impl->CreateFile(normalized_path, size, option));
}
return ResultSuccess();
R_SUCCEED();
}
Result FileSystemAccessor::DeleteFile(const char *path) {
R_TRY(ValidatePath(m_name.str, path));
return m_impl->DeleteFile(path);
/* Create path. */
fs::Path normalized_path;
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
R_RETURN(m_impl->DeleteFile(normalized_path));
}
Result FileSystemAccessor::CreateDirectory(const char *path) {
R_TRY(ValidatePath(m_name.str, path));
return m_impl->CreateDirectory(path);
/* Create path. */
fs::Path normalized_path;
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
R_RETURN(m_impl->CreateDirectory(normalized_path));
}
Result FileSystemAccessor::DeleteDirectory(const char *path) {
R_TRY(ValidatePath(m_name.str, path));
return m_impl->DeleteDirectory(path);
/* Create path. */
fs::Path normalized_path;
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
R_RETURN(m_impl->DeleteDirectory(normalized_path));
}
Result FileSystemAccessor::DeleteDirectoryRecursively(const char *path) {
R_TRY(ValidatePath(m_name.str, path));
return m_impl->DeleteDirectoryRecursively(path);
/* Create path. */
fs::Path normalized_path;
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
R_RETURN(m_impl->DeleteDirectoryRecursively(normalized_path));
}
Result FileSystemAccessor::RenameFile(const char *old_path, const char *new_path) {
R_TRY(ValidatePath(m_name.str, old_path));
R_TRY(ValidatePath(m_name.str, new_path));
/* Create path. */
fs::Path normalized_old_path;
fs::Path normalized_new_path;
R_TRY(this->SetUpPath(std::addressof(normalized_old_path), old_path));
R_TRY(this->SetUpPath(std::addressof(normalized_new_path), new_path));
if (m_path_cache_attached) {
/* TODO: Path cache */
R_TRY(m_impl->RenameFile(old_path, new_path));
R_TRY(m_impl->RenameFile(normalized_old_path, normalized_new_path));
} else {
R_TRY(m_impl->RenameFile(old_path, new_path));
R_TRY(m_impl->RenameFile(normalized_old_path, normalized_new_path));
}
return ResultSuccess();
R_SUCCEED();
}
Result FileSystemAccessor::RenameDirectory(const char *old_path, const char *new_path) {
R_TRY(ValidatePath(m_name.str, old_path));
R_TRY(ValidatePath(m_name.str, new_path));
/* Create path. */
fs::Path normalized_old_path;
fs::Path normalized_new_path;
R_TRY(this->SetUpPath(std::addressof(normalized_old_path), old_path));
R_TRY(this->SetUpPath(std::addressof(normalized_new_path), new_path));
if (m_path_cache_attached) {
/* TODO: Path cache */
R_TRY(m_impl->RenameDirectory(old_path, new_path));
R_TRY(m_impl->RenameDirectory(normalized_old_path, normalized_new_path));
} else {
R_TRY(m_impl->RenameDirectory(old_path, new_path));
R_TRY(m_impl->RenameDirectory(normalized_old_path, normalized_new_path));
}
return ResultSuccess();
R_SUCCEED();
}
Result FileSystemAccessor::GetEntryType(DirectoryEntryType *out, const char *path) {
R_TRY(ValidatePath(m_name.str, path));
return m_impl->GetEntryType(out, path);
/* Create path. */
fs::Path normalized_path;
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
R_RETURN(m_impl->GetEntryType(out, normalized_path));
}
Result FileSystemAccessor::OpenFile(std::unique_ptr<FileAccessor> *out_file, const char *path, OpenMode mode) {
R_TRY(ValidatePath(m_name.str, path));
/* Create path. */
fs::Path normalized_path;
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
std::unique_ptr<fsa::IFile> file;
R_TRY(m_impl->OpenFile(std::addressof(file), path, mode));
R_TRY(m_impl->OpenFile(std::addressof(file), normalized_path, mode));
auto accessor = new FileAccessor(std::move(file), this, mode);
R_UNLESS(accessor != nullptr, fs::ResultAllocationFailureInFileSystemAccessorA());
@@ -187,14 +239,16 @@ namespace ams::fs::impl {
}
out_file->reset(accessor);
return ResultSuccess();
R_SUCCEED();
}
Result FileSystemAccessor::OpenDirectory(std::unique_ptr<DirectoryAccessor> *out_dir, const char *path, OpenDirectoryMode mode) {
R_TRY(ValidatePath(m_name.str, path));
/* Create path. */
fs::Path normalized_path;
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
std::unique_ptr<fsa::IDirectory> dir;
R_TRY(m_impl->OpenDirectory(std::addressof(dir), path, mode));
R_TRY(m_impl->OpenDirectory(std::addressof(dir), normalized_path, mode));
auto accessor = new DirectoryAccessor(std::move(dir), *this);
R_UNLESS(accessor != nullptr, fs::ResultAllocationFailureInFileSystemAccessorB());
@@ -205,7 +259,7 @@ namespace ams::fs::impl {
}
out_dir->reset(accessor);
return ResultSuccess();
R_SUCCEED();
}
Result FileSystemAccessor::Commit() {
@@ -213,30 +267,47 @@ namespace ams::fs::impl {
std::scoped_lock lk(m_open_list_lock);
R_ABORT_UNLESS(ValidateNoOpenWriteModeFiles(m_open_file_list));
}
return m_impl->Commit();
R_RETURN(m_impl->Commit());
}
Result FileSystemAccessor::GetFreeSpaceSize(s64 *out, const char *path) {
R_TRY(ValidatePath(m_name.str, path));
return m_impl->GetFreeSpaceSize(out, path);
/* Create path. */
fs::Path normalized_path;
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
R_RETURN(m_impl->GetFreeSpaceSize(out, normalized_path));
}
Result FileSystemAccessor::GetTotalSpaceSize(s64 *out, const char *path) {
R_TRY(ValidatePath(m_name.str, path));
return m_impl->GetTotalSpaceSize(out, path);
/* Create path. */
fs::Path normalized_path;
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
R_RETURN(m_impl->GetTotalSpaceSize(out, normalized_path));
}
Result FileSystemAccessor::CleanDirectoryRecursively(const char *path) {
R_TRY(ValidatePath(m_name.str, path));
return m_impl->CleanDirectoryRecursively(path);
/* Create path. */
fs::Path normalized_path;
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
R_RETURN(m_impl->CleanDirectoryRecursively(normalized_path));
}
Result FileSystemAccessor::GetFileTimeStampRaw(FileTimeStampRaw *out, const char *path) {
return m_impl->GetFileTimeStampRaw(out, path);
/* Create path. */
fs::Path normalized_path;
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
R_RETURN(m_impl->GetFileTimeStampRaw(out, normalized_path));
}
Result FileSystemAccessor::QueryEntry(char *dst, size_t dst_size, const char *src, size_t src_size, fsa::QueryId query, const char *path) {
return m_impl->QueryEntry(dst, dst_size, src, src_size, query, path);
/* Create path. */
fs::Path normalized_path;
R_TRY(this->SetUpPath(std::addressof(normalized_path), path));
R_RETURN(m_impl->QueryEntry(dst, dst_size, src, src_size, query, normalized_path));
}