Merge pull request #7010 from Morph1984/fs-timestamp

vfs: Partially implement GetFileTimeStampRaw
This commit is contained in:
bunnei 2021-09-15 20:13:26 -07:00 committed by GitHub
commit f6d5444293
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 83 additions and 1 deletions

View File

@ -273,6 +273,10 @@ VirtualFile VfsDirectory::GetFile(std::string_view name) const {
return iter == files.end() ? nullptr : *iter;
}
FileTimeStampRaw VfsDirectory::GetFileTimeStamp([[maybe_unused]] std::string_view path) const {
return {};
}
VirtualDir VfsDirectory::GetSubdirectory(std::string_view name) const {
const auto& subs = GetSubdirectories();
const auto iter = std::find_if(subs.begin(), subs.end(),

View File

@ -199,6 +199,9 @@ public:
// file with name.
virtual VirtualFile GetFile(std::string_view name) const;
// Returns a struct containing the file's timestamp.
virtual FileTimeStampRaw GetFileTimeStamp(std::string_view path) const;
// Returns a vector containing all of the subdirectories in this directory.
virtual std::vector<VirtualDir> GetSubdirectories() const = 0;
// Returns the directory with name matching name. Returns nullptr if directory dosen't have a

View File

@ -13,6 +13,13 @@
#include "common/logging/log.h"
#include "core/file_sys/vfs_real.h"
// For FileTimeStampRaw
#include <sys/stat.h>
#ifdef _MSC_VER
#define stat _stat64
#endif
namespace FileSys {
namespace FS = Common::FS;
@ -392,6 +399,28 @@ std::vector<VirtualFile> RealVfsDirectory::GetFiles() const {
return IterateEntries<RealVfsFile, VfsFile>();
}
FileTimeStampRaw RealVfsDirectory::GetFileTimeStamp(std::string_view path_) const {
const auto full_path = FS::SanitizePath(path + '/' + std::string(path_));
const auto fs_path = std::filesystem::path{FS::ToU8String(full_path)};
struct stat file_status;
#ifdef _WIN32
const auto stat_result = _wstat64(fs_path.c_str(), &file_status);
#else
const auto stat_result = stat(fs_path.c_str(), &file_status);
#endif
if (stat_result != 0) {
return {};
}
return {
.created{static_cast<u64>(file_status.st_ctime)},
.accessed{static_cast<u64>(file_status.st_atime)},
.modified{static_cast<u64>(file_status.st_mtime)},
};
}
std::vector<VirtualDir> RealVfsDirectory::GetSubdirectories() const {
return IterateEntries<RealVfsDirectory, VfsDirectory>();
}

View File

@ -86,6 +86,7 @@ public:
VirtualDir CreateDirectoryRelative(std::string_view relative_path) override;
bool DeleteSubdirectoryRecursive(std::string_view name) override;
std::vector<VirtualFile> GetFiles() const override;
FileTimeStampRaw GetFileTimeStamp(std::string_view path) const override;
std::vector<VirtualDir> GetSubdirectories() const override;
bool IsWritable() const override;
bool IsReadable() const override;

View File

@ -6,6 +6,8 @@
#include <memory>
#include "common/common_types.h"
namespace FileSys {
class VfsDirectory;
@ -18,4 +20,11 @@ using VirtualDir = std::shared_ptr<VfsDirectory>;
using VirtualFile = std::shared_ptr<VfsFile>;
using VirtualFilesystem = std::shared_ptr<VfsFilesystem>;
struct FileTimeStampRaw {
u64 created{};
u64 accessed{};
u64 modified{};
u64 padding{};
};
} // namespace FileSys

View File

@ -261,6 +261,18 @@ ResultVal<FileSys::EntryType> VfsDirectoryServiceWrapper::GetEntryType(
return FileSys::ERROR_PATH_NOT_FOUND;
}
ResultVal<FileSys::FileTimeStampRaw> VfsDirectoryServiceWrapper::GetFileTimeStampRaw(
const std::string& path) const {
auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(path));
if (dir == nullptr) {
return FileSys::ERROR_PATH_NOT_FOUND;
}
if (GetEntryType(path).Failed()) {
return FileSys::ERROR_PATH_NOT_FOUND;
}
return MakeResult(dir->GetFileTimeStamp(Common::FS::GetFilename(path)));
}
FileSystemController::FileSystemController(Core::System& system_) : system{system_} {}
FileSystemController::~FileSystemController() = default;

View File

@ -240,6 +240,12 @@ public:
*/
ResultVal<FileSys::EntryType> GetEntryType(const std::string& path) const;
/**
* Get the timestamp of the specified path
* @return The timestamp of the specified path or error code
*/
ResultVal<FileSys::FileTimeStampRaw> GetFileTimeStampRaw(const std::string& path) const;
private:
FileSys::VirtualDir backing;
};

View File

@ -326,7 +326,7 @@ public:
{11, &IFileSystem::GetFreeSpaceSize, "GetFreeSpaceSize"},
{12, &IFileSystem::GetTotalSpaceSize, "GetTotalSpaceSize"},
{13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"},
{14, nullptr, "GetFileTimeStampRaw"},
{14, &IFileSystem::GetFileTimeStampRaw, "GetFileTimeStampRaw"},
{15, nullptr, "QueryEntry"},
};
RegisterHandlers(functions);
@ -501,6 +501,24 @@ public:
rb.Push(size.get_total_size());
}
void GetFileTimeStampRaw(Kernel::HLERequestContext& ctx) {
const auto file_buffer = ctx.ReadBuffer();
const std::string name = Common::StringFromBuffer(file_buffer);
LOG_WARNING(Service_FS, "(Partial Implementation) called. file={}", name);
auto result = backend.GetFileTimeStampRaw(name);
if (result.Failed()) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result.Code());
return;
}
IPC::ResponseBuilder rb{ctx, 10};
rb.Push(ResultSuccess);
rb.PushRaw(*result);
}
private:
VfsDirectoryServiceWrapper backend;
SizeGetter size;