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; 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 { VirtualDir VfsDirectory::GetSubdirectory(std::string_view name) const {
const auto& subs = GetSubdirectories(); const auto& subs = GetSubdirectories();
const auto iter = std::find_if(subs.begin(), subs.end(), const auto iter = std::find_if(subs.begin(), subs.end(),

View File

@ -199,6 +199,9 @@ public:
// file with name. // file with name.
virtual VirtualFile GetFile(std::string_view name) const; 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. // Returns a vector containing all of the subdirectories in this directory.
virtual std::vector<VirtualDir> GetSubdirectories() const = 0; virtual std::vector<VirtualDir> GetSubdirectories() const = 0;
// Returns the directory with name matching name. Returns nullptr if directory dosen't have a // 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 "common/logging/log.h"
#include "core/file_sys/vfs_real.h" #include "core/file_sys/vfs_real.h"
// For FileTimeStampRaw
#include <sys/stat.h>
#ifdef _MSC_VER
#define stat _stat64
#endif
namespace FileSys { namespace FileSys {
namespace FS = Common::FS; namespace FS = Common::FS;
@ -392,6 +399,28 @@ std::vector<VirtualFile> RealVfsDirectory::GetFiles() const {
return IterateEntries<RealVfsFile, VfsFile>(); 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 { std::vector<VirtualDir> RealVfsDirectory::GetSubdirectories() const {
return IterateEntries<RealVfsDirectory, VfsDirectory>(); return IterateEntries<RealVfsDirectory, VfsDirectory>();
} }

View File

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

View File

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

View File

@ -261,6 +261,18 @@ ResultVal<FileSys::EntryType> VfsDirectoryServiceWrapper::GetEntryType(
return FileSys::ERROR_PATH_NOT_FOUND; 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(Core::System& system_) : system{system_} {}
FileSystemController::~FileSystemController() = default; FileSystemController::~FileSystemController() = default;

View File

@ -240,6 +240,12 @@ public:
*/ */
ResultVal<FileSys::EntryType> GetEntryType(const std::string& path) const; 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: private:
FileSys::VirtualDir backing; FileSys::VirtualDir backing;
}; };

View File

@ -326,7 +326,7 @@ public:
{11, &IFileSystem::GetFreeSpaceSize, "GetFreeSpaceSize"}, {11, &IFileSystem::GetFreeSpaceSize, "GetFreeSpaceSize"},
{12, &IFileSystem::GetTotalSpaceSize, "GetTotalSpaceSize"}, {12, &IFileSystem::GetTotalSpaceSize, "GetTotalSpaceSize"},
{13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"}, {13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"},
{14, nullptr, "GetFileTimeStampRaw"}, {14, &IFileSystem::GetFileTimeStampRaw, "GetFileTimeStampRaw"},
{15, nullptr, "QueryEntry"}, {15, nullptr, "QueryEntry"},
}; };
RegisterHandlers(functions); RegisterHandlers(functions);
@ -501,6 +501,24 @@ public:
rb.Push(size.get_total_size()); 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: private:
VfsDirectoryServiceWrapper backend; VfsDirectoryServiceWrapper backend;
SizeGetter size; SizeGetter size;