mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-04-26 12:55:14 -06:00
Upgraded stat
Negative fd safeguard (EBADF) Stat time is now tracked Catching unknown open() flags
This commit is contained in:
parent
7b9cc2d481
commit
552a43b767
@ -138,19 +138,18 @@ s32 HostIO_POSIX::Stat(const fs::path& path, Libraries::Kernel::OrbisKernelStat*
|
||||
// statbuf->st_ino = st.st_ino;
|
||||
statbuf->st_mode = st.st_mode;
|
||||
// statbuf->st_nlink = st.st_nlink;
|
||||
// statbuf->st_uid = st.st_uid; // always 0
|
||||
// statbuf->st_gid = st.st_gid; // always 0
|
||||
statbuf->st_uid = 0; // st.st_uid; // always 0
|
||||
statbuf->st_gid = 0; // st.st_gid; // always 0
|
||||
// statbuf->st_rdev = st.st_rdev;
|
||||
statbuf->st_atim.tv_sec = st.st_atim.tv_sec;
|
||||
statbuf->st_atim.tv_nsec = st.st_atim.tv_nsec;
|
||||
statbuf->st_mtim.tv_sec = st.st_mtim.tv_sec;
|
||||
statbuf->st_mtim.tv_nsec = st.st_mtim.tv_nsec;
|
||||
statbuf->st_ctim.tv_sec = st.st_ctim.tv_sec;
|
||||
statbuf->st_ctim.tv_nsec = st.st_ctim.tv_nsec;
|
||||
statbuf->st_atim.tv_sec = st.st_atim.tv_sec; //
|
||||
statbuf->st_mtim.tv_sec = st.st_mtim.tv_sec; //
|
||||
statbuf->st_ctim.tv_sec = st.st_ctim.tv_sec; //
|
||||
statbuf->st_birthtim.tv_sec = st.st_ctim.tv_sec; // just assuming these are the same
|
||||
statbuf->st_birthtim.tv_nsec = 0; // st.st_ctim.tv_nsec;
|
||||
|
||||
statbuf->st_size = st.st_size;
|
||||
statbuf->st_blocks = st.st_blocks;
|
||||
statbuf->st_blksize = st.st_blksize;
|
||||
// statbuf->st_blocks = st.st_blocks;
|
||||
// statbuf->st_blksize = st.st_blksize;
|
||||
|
||||
// statbuf->st_flags = st.st_;
|
||||
// statbuf->st_gen = st.st_;
|
||||
@ -170,19 +169,27 @@ s32 HostIO_POSIX::FStat(const s32 fd, Libraries::Kernel::OrbisKernelStat* statbu
|
||||
// handled by QFS
|
||||
// statbuf->st_dev = st.st_dev;
|
||||
// statbuf->st_ino = st.st_ino;
|
||||
// statbuf->st_nlink = st.st_nlink;
|
||||
|
||||
// TODO: make working
|
||||
statbuf->st_mode = st.st_mode;
|
||||
// statbuf->st_nlink = st.st_nlink;
|
||||
statbuf->st_uid = 0; // st.st_uid; // always 0
|
||||
statbuf->st_gid = 0; // st.st_gid; // always 0
|
||||
// statbuf->st_rdev = st.st_rdev;
|
||||
statbuf->st_atim.tv_sec = st.st_atim.tv_sec; //
|
||||
statbuf->st_atim.tv_nsec = 0; // st.st_atim.tv_nsec;
|
||||
statbuf->st_mtim.tv_sec = st.st_mtim.tv_sec; //
|
||||
statbuf->st_mtim.tv_nsec = 0; // st.st_mtim.tv_nsec;
|
||||
statbuf->st_ctim.tv_sec = st.st_ctim.tv_sec; //
|
||||
statbuf->st_ctim.tv_nsec = 0; // st.st_ctim.tv_nsec;
|
||||
statbuf->st_birthtim.tv_sec = st.st_ctim.tv_sec; // just assuming these are the same
|
||||
statbuf->st_birthtim.tv_nsec = 0; // st.st_ctim.tv_nsec;
|
||||
|
||||
statbuf->st_size = st.st_size;
|
||||
statbuf->st_blksize = st.st_blksize;
|
||||
statbuf->st_blocks = st.st_blocks;
|
||||
statbuf->st_atim.tv_sec = st.st_atim.tv_sec;
|
||||
statbuf->st_atim.tv_nsec = st.st_atim.tv_nsec;
|
||||
statbuf->st_mtim.tv_sec = st.st_mtim.tv_sec;
|
||||
statbuf->st_mtim.tv_nsec = st.st_mtim.tv_nsec;
|
||||
statbuf->st_ctim.tv_sec = st.st_ctim.tv_sec;
|
||||
statbuf->st_ctim.tv_nsec = st.st_ctim.tv_nsec;
|
||||
// statbuf->st_blocks = st.st_blocks;
|
||||
// statbuf->st_blksize = st.st_blksize;
|
||||
|
||||
// statbuf->st_flags = st.st_;
|
||||
// statbuf->st_gen = st.st_;
|
||||
// statbuf->st_lspare = st.st_;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -24,6 +24,9 @@ HostIO_Virtual::HostIO_Virtual() = default;
|
||||
HostIO_Virtual::~HostIO_Virtual() = default;
|
||||
|
||||
s32 HostIO_Virtual::Open(const fs::path& path, s32 flags, u16 mode) {
|
||||
if (int remainder = flags & ~__QUASI_O_ALLFLAGS_AT_ONCE; remainder != 0)
|
||||
LOG_WARNING(Kernel_Fs, "open() received unknown flags: {:x}", remainder);
|
||||
|
||||
if (nullptr == this->res)
|
||||
return -QUASI_EINVAL;
|
||||
|
||||
|
||||
@ -25,8 +25,6 @@ s32 HostIO_Win32::Creat(const fs::path& path, u16 mode) {
|
||||
|
||||
s32 HostIO_Win32::Close(const s32 fd) {
|
||||
errno = 0;
|
||||
if (fd < 0)
|
||||
return -EBADF;
|
||||
s32 status = _close(fd);
|
||||
return 0 == status ? 0 : -errno;
|
||||
}
|
||||
|
||||
@ -15,4 +15,9 @@
|
||||
#define QUASI_O_EXCL 0x0800
|
||||
#define QUASI_O_DSYNC 0x1000
|
||||
#define QUASI_O_DIRECT 0x00010000
|
||||
#define QUASI_O_DIRECTORY 0x00020000
|
||||
#define QUASI_O_DIRECTORY 0x00020000
|
||||
|
||||
#define __QUASI_O_ALLFLAGS_AT_ONCE \
|
||||
(QUASI_O_RDONLY | QUASI_O_WRONLY | QUASI_O_RDWR | QUASI_O_NONBLOCK | QUASI_O_APPEND | \
|
||||
QUASI_O_FSYNC | QUASI_O_SYNC | QUASI_O_CREAT | QUASI_O_TRUNC | QUASI_O_EXCL | QUASI_O_DSYNC | \
|
||||
QUASI_O_DIRECT | QUASI_O_DIRECTORY)
|
||||
@ -2,7 +2,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ctime>
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
|
||||
#include "common/types.h"
|
||||
#include "common/va_ctx.h"
|
||||
@ -21,6 +23,17 @@ public:
|
||||
st.st_nlink = 0;
|
||||
st.st_uid = 0;
|
||||
st.st_gid = 0;
|
||||
|
||||
static_assert(sizeof(time_t) == 8, "Time is not stored in 64 bits");
|
||||
|
||||
st.st_birthtim.tv_sec = time(0);
|
||||
st.st_birthtim.tv_nsec = 0;
|
||||
st.st_ctim.tv_sec = time(0);
|
||||
st.st_ctim.tv_nsec = 0;
|
||||
st.st_mtim.tv_sec = time(0);
|
||||
st.st_mtim.tv_nsec = 0;
|
||||
st.st_atim.tv_sec = time(0);
|
||||
st.st_atim.tv_nsec = 0;
|
||||
}
|
||||
|
||||
virtual ~Inode() = default;
|
||||
@ -29,6 +42,8 @@ public:
|
||||
return -QUASI_ENOTTY;
|
||||
}
|
||||
|
||||
// these don't make sense with anything that's not a device
|
||||
// kept here to verify
|
||||
virtual s64 read(void* buf, u64 count) {
|
||||
return -QUASI_EBADF;
|
||||
}
|
||||
@ -37,6 +52,7 @@ public:
|
||||
return -QUASI_EBADF;
|
||||
}
|
||||
|
||||
// these 4 make sense everywhere
|
||||
virtual s64 pread(void* buf, u64 count, s64 offset) {
|
||||
return -QUASI_EBADF;
|
||||
}
|
||||
@ -161,6 +177,7 @@ public:
|
||||
int chmod(u16 mode) {
|
||||
u16* st_mode = &this->st.st_mode;
|
||||
*st_mode = ((*st_mode) & (~0x1FF)) | (mode & 0x1FF);
|
||||
st.st_birthtim.tv_sec = time(0);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -79,6 +79,11 @@ public:
|
||||
blkid_t GetBlkId(void) {
|
||||
return this->block_id;
|
||||
}
|
||||
void AdjustStat(Libraries::Kernel::OrbisKernelStat* statbuf) {
|
||||
auto& s = statbuf->st_size;
|
||||
statbuf->st_blksize = this->block_size;
|
||||
statbuf->st_blocks = (1 + (s / this->ioblock_size)) * this->ioblock_size / this->block_size;
|
||||
}
|
||||
inode_ptr GetInodeByFileno(fileno_t fileno);
|
||||
|
||||
int Resolve(fs::path& path, Resolved& res);
|
||||
|
||||
@ -420,6 +420,7 @@ void QFS::SyncHostImpl(partition_ptr part) {
|
||||
LOG_ERROR(Kernel_Fs, "Cannot stat file: {}", entry_path.string());
|
||||
continue;
|
||||
}
|
||||
part->AdjustStat(&new_inode->st);
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
LOG_CRITICAL(Kernel_Fs, "An error occurred when syncing [{}]: {}", host_path.string(),
|
||||
|
||||
@ -16,6 +16,7 @@ inode_ptr QuasiDirectory::lookup(const std::string& name) {
|
||||
auto it = entries.find(name);
|
||||
if (it == entries.end())
|
||||
return nullptr;
|
||||
st.st_atim.tv_sec = time(0);
|
||||
return it->second;
|
||||
}
|
||||
|
||||
@ -27,6 +28,7 @@ int QuasiDirectory::link(const std::string& name, inode_ptr child) {
|
||||
entries[name] = child;
|
||||
if (!child->is_link())
|
||||
child->st.st_nlink++;
|
||||
st.st_mtim.tv_sec = time(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -54,10 +56,12 @@ int QuasiDirectory::unlink(const std::string& name) {
|
||||
// not referenced in original location anymore
|
||||
target->st.st_nlink--;
|
||||
entries.erase(it);
|
||||
st.st_mtim.tv_sec = time(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<std::string> QuasiDirectory::list() {
|
||||
st.st_atim.tv_sec = time(0);
|
||||
std::vector<std::string> r;
|
||||
for (auto& p : entries)
|
||||
r.push_back(p.first);
|
||||
|
||||
@ -11,15 +11,17 @@ s64 QuasiFile::pread(void* buf, size_t count, s64 offset) {
|
||||
auto size = &this->st.st_size;
|
||||
auto end_pos = offset + count;
|
||||
|
||||
st.st_atim.tv_sec = time(0);
|
||||
return end_pos > *size ? *size - offset : count;
|
||||
}
|
||||
|
||||
s64 QuasiFile::pwrite(const void* buf, size_t count, s64 offset) {
|
||||
auto size = &this->st.st_size;
|
||||
auto& size = this->st.st_size;
|
||||
auto end_pos = offset + count;
|
||||
|
||||
*size = end_pos > *size ? end_pos : *size;
|
||||
size = end_pos > size ? end_pos : size;
|
||||
|
||||
st.st_mtim.tv_sec = time(0);
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -27,6 +29,7 @@ s32 QuasiFile::ftruncate(s64 length) {
|
||||
if (length < 0)
|
||||
return -QUASI_EINVAL;
|
||||
this->st.st_size = length;
|
||||
st.st_mtim.tv_sec = time(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@ Symlink::Symlink(fs::path target) : target(target) {
|
||||
}
|
||||
|
||||
fs::path Symlink::follow(void) {
|
||||
st.st_atim.tv_sec = time(0);
|
||||
return target;
|
||||
}
|
||||
} // namespace QuasiFS
|
||||
@ -20,6 +20,7 @@ s64 VirtualFile::pread(void* buf, size_t count, s64 offset) {
|
||||
static_cast<char*>(buf)[idx] = c;
|
||||
}
|
||||
|
||||
st.st_atim.tv_sec = time(0);
|
||||
return read_amt;
|
||||
}
|
||||
|
||||
@ -34,6 +35,7 @@ s64 VirtualFile::pwrite(const void* buf, size_t count, s64 offset) {
|
||||
for (u64 idx = offset; idx < *size; idx++)
|
||||
this->data[idx] = static_cast<const char*>(buf)[idx];
|
||||
|
||||
st.st_mtim.tv_sec = time(0);
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -42,6 +44,7 @@ s32 VirtualFile::ftruncate(s64 length) {
|
||||
return -QUASI_EINVAL;
|
||||
this->data.resize(length, 0);
|
||||
this->st.st_size = length;
|
||||
st.st_mtim.tv_sec = time(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -119,13 +119,18 @@ s32 QFS::OperationImpl::Creat(const fs::path& path, u16 mode) {
|
||||
};
|
||||
|
||||
s32 QFS::OperationImpl::Close(s32 fd) {
|
||||
if (fd < 0)
|
||||
return -QUASI_EBADF;
|
||||
|
||||
fd_handle_ptr handle = qfs.GetHandle(fd);
|
||||
if (nullptr == handle)
|
||||
return -QUASI_EBADF;
|
||||
|
||||
if (fd <= 2)
|
||||
LOG_ERROR(Kernel_Fs, "Closing std stream, this will have consequences fd={}", fd);
|
||||
|
||||
// if it fails, it fails
|
||||
if (int hio_status = qfs.hio_driver.Close(handle->host_fd); hio_status < 0)
|
||||
return hio_status;
|
||||
int hio_status = qfs.hio_driver.Close(handle->host_fd);
|
||||
|
||||
// no further action is required, this is pro-forma
|
||||
qfs.vio_driver.Close(fd);
|
||||
@ -135,11 +140,10 @@ s32 QFS::OperationImpl::Close(s32 fd) {
|
||||
|
||||
if (fd < (qfs.open_fd.size() - 1)) {
|
||||
qfs.open_fd.at(fd) = nullptr;
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
qfs.open_fd.pop_back();
|
||||
|
||||
qfs.open_fd.pop_back();
|
||||
return 0;
|
||||
return hio_status;
|
||||
}
|
||||
|
||||
s32 QFS::OperationImpl::LinkSymbolic(const fs::path& src, const fs::path& dst) {
|
||||
@ -323,6 +327,9 @@ s32 QFS::OperationImpl::Unlink(const fs::path& path) {
|
||||
}
|
||||
|
||||
s32 QFS::OperationImpl::Flush(const s32 fd) {
|
||||
if (fd < 0)
|
||||
return -QUASI_EBADF;
|
||||
|
||||
fd_handle_ptr handle = qfs.GetHandle(fd);
|
||||
if (nullptr == handle)
|
||||
return -QUASI_EBADF;
|
||||
@ -354,6 +361,9 @@ s32 QFS::OperationImpl::Flush(const s32 fd) {
|
||||
}
|
||||
|
||||
s32 QFS::OperationImpl::FSync(const s32 fd) {
|
||||
if (fd < 0)
|
||||
return -QUASI_EBADF;
|
||||
|
||||
fd_handle_ptr handle = qfs.GetHandle(fd);
|
||||
if (nullptr == handle)
|
||||
return -QUASI_EBADF;
|
||||
@ -422,6 +432,9 @@ s32 QFS::OperationImpl::Truncate(const fs::path& path, u64 length) {
|
||||
}
|
||||
|
||||
s32 QFS::OperationImpl::FTruncate(const s32 fd, u64 length) {
|
||||
if (fd < 0)
|
||||
return -QUASI_EBADF;
|
||||
|
||||
fd_handle_ptr handle = qfs.GetHandle(fd);
|
||||
if (nullptr == handle)
|
||||
return -QUASI_EBADF;
|
||||
@ -455,6 +468,9 @@ s32 QFS::OperationImpl::FTruncate(const s32 fd, u64 length) {
|
||||
}
|
||||
|
||||
s64 QFS::OperationImpl::LSeek(const s32 fd, u64 offset, SeekOrigin origin) {
|
||||
if (fd < 0)
|
||||
return -QUASI_EBADF;
|
||||
|
||||
fd_handle_ptr handle = qfs.GetHandle(fd);
|
||||
if (nullptr == handle)
|
||||
return -QUASI_EBADF;
|
||||
@ -497,6 +513,9 @@ void UpdateStatFromHost(Libraries::Kernel::OrbisKernelStat* vfs,
|
||||
}
|
||||
|
||||
s64 QFS::OperationImpl::Write(const s32 fd, const void* buf, u64 count) {
|
||||
if (fd < 0)
|
||||
return -QUASI_EBADF;
|
||||
|
||||
fd_handle_ptr handle = qfs.GetHandle(fd);
|
||||
if (nullptr == handle)
|
||||
return -QUASI_EBADF;
|
||||
@ -528,6 +547,9 @@ s64 QFS::OperationImpl::Write(const s32 fd, const void* buf, u64 count) {
|
||||
}
|
||||
|
||||
s64 QFS::OperationImpl::PWrite(const s32 fd, const void* buf, u64 count, u64 offset) {
|
||||
if (fd < 0)
|
||||
return -QUASI_EBADF;
|
||||
|
||||
fd_handle_ptr handle = qfs.GetHandle(fd);
|
||||
if (nullptr == handle)
|
||||
return -QUASI_EBADF;
|
||||
@ -559,6 +581,9 @@ s64 QFS::OperationImpl::PWrite(const s32 fd, const void* buf, u64 count, u64 off
|
||||
};
|
||||
|
||||
s64 QFS::OperationImpl::Read(const s32 fd, void* buf, u64 count) {
|
||||
if (fd < 0)
|
||||
return -QUASI_EBADF;
|
||||
|
||||
fd_handle_ptr handle = qfs.GetHandle(fd);
|
||||
if (nullptr == handle)
|
||||
return -QUASI_EBADF;
|
||||
@ -590,6 +615,9 @@ s64 QFS::OperationImpl::Read(const s32 fd, void* buf, u64 count) {
|
||||
}
|
||||
|
||||
s64 QFS::OperationImpl::PRead(const s32 fd, void* buf, u64 count, u64 offset) {
|
||||
if (fd < 0)
|
||||
return -QUASI_EBADF;
|
||||
|
||||
fd_handle_ptr handle = qfs.GetHandle(fd);
|
||||
if (nullptr == handle)
|
||||
return -QUASI_EBADF;
|
||||
@ -710,93 +738,98 @@ s32 QFS::OperationImpl::Stat(const fs::path& path, Libraries::Kernel::OrbisKerne
|
||||
}
|
||||
|
||||
partition_ptr part = res.mountpoint;
|
||||
bool host_used = false;
|
||||
int hio_status = 0;
|
||||
// bool host_used = false;
|
||||
// int hio_status = 0;
|
||||
int vio_status = 0;
|
||||
|
||||
Libraries::Kernel::OrbisKernelStat hio_stat;
|
||||
// Libraries::Kernel::OrbisKernelStat hio_stat;
|
||||
Libraries::Kernel::OrbisKernelStat vio_stat;
|
||||
|
||||
if (part->IsHostMounted()) {
|
||||
fs::path host_path_target{};
|
||||
if (int hostpath_status = part->GetHostPath(host_path_target, res.local_path);
|
||||
hostpath_status != 0)
|
||||
return hostpath_status;
|
||||
// if (part->IsHostMounted()) {
|
||||
// fs::path host_path_target{};
|
||||
// if (int hostpath_status = part->GetHostPath(host_path_target, res.local_path);
|
||||
// hostpath_status != 0)
|
||||
// return hostpath_status;
|
||||
|
||||
if (hio_status = qfs.hio_driver.Stat(host_path_target, &hio_stat); 0 != hio_status) {
|
||||
// hosts operation must succeed in order to continue
|
||||
return hio_status;
|
||||
}
|
||||
// if (hio_status = qfs.hio_driver.Stat(host_path_target, &hio_stat); 0 != hio_status) {
|
||||
// // hosts operation must succeed in order to continue
|
||||
// return hio_status;
|
||||
// }
|
||||
|
||||
host_used = true;
|
||||
}
|
||||
// host_used = true;
|
||||
// }
|
||||
|
||||
qfs.vio_driver.SetCtx(&res, host_used, nullptr);
|
||||
// qfs.vio_driver.SetCtx(&res, host_used, nullptr);
|
||||
qfs.vio_driver.SetCtx(&res, false, nullptr);
|
||||
vio_status = qfs.vio_driver.Stat(res.local_path, &vio_stat);
|
||||
qfs.vio_driver.ClearCtx();
|
||||
|
||||
if (host_used) {
|
||||
vio_stat.st_mode = hio_stat.st_mode;
|
||||
vio_stat.st_size = hio_stat.st_size;
|
||||
vio_stat.st_blksize = hio_stat.st_blksize;
|
||||
vio_stat.st_blocks = hio_stat.st_blocks;
|
||||
vio_stat.st_atim.tv_sec = hio_stat.st_atim.tv_sec;
|
||||
vio_stat.st_atim.tv_nsec = hio_stat.st_atim.tv_nsec;
|
||||
vio_stat.st_mtim.tv_sec = hio_stat.st_mtim.tv_sec;
|
||||
vio_stat.st_mtim.tv_nsec = hio_stat.st_mtim.tv_nsec;
|
||||
vio_stat.st_ctim.tv_sec = hio_stat.st_ctim.tv_sec;
|
||||
vio_stat.st_ctim.tv_nsec = hio_stat.st_ctim.tv_nsec;
|
||||
}
|
||||
// if (host_used) {
|
||||
// vio_stat.st_mode = hio_stat.st_mode;
|
||||
// vio_stat.st_size = hio_stat.st_size;
|
||||
// vio_stat.st_blksize = hio_stat.st_blksize;
|
||||
// vio_stat.st_blocks = hio_stat.st_blocks;
|
||||
// vio_stat.st_atim.tv_sec = hio_stat.st_atim.tv_sec;
|
||||
// vio_stat.st_atim.tv_nsec = hio_stat.st_atim.tv_nsec;
|
||||
// vio_stat.st_mtim.tv_sec = hio_stat.st_mtim.tv_sec;
|
||||
// vio_stat.st_mtim.tv_nsec = hio_stat.st_mtim.tv_nsec;
|
||||
// vio_stat.st_ctim.tv_sec = hio_stat.st_ctim.tv_sec;
|
||||
// vio_stat.st_ctim.tv_nsec = hio_stat.st_ctim.tv_nsec;
|
||||
// }
|
||||
|
||||
memcpy(statbuf, &vio_stat, sizeof(Libraries::Kernel::OrbisKernelStat));
|
||||
|
||||
if (host_used && (hio_status != vio_status))
|
||||
LOG_ERROR(Kernel_Fs, "Host returned {}, but virtual driver returned {}", hio_status,
|
||||
vio_status);
|
||||
// if (host_used && (hio_status != vio_status))
|
||||
// LOG_ERROR(Kernel_Fs, "Host returned {}, but virtual driver returned {}", hio_status,
|
||||
// vio_status);
|
||||
|
||||
return vio_status;
|
||||
}
|
||||
|
||||
s32 QFS::OperationImpl::FStat(const s32 fd, Libraries::Kernel::OrbisKernelStat* statbuf) {
|
||||
if (fd < 0)
|
||||
return -QUASI_EBADF;
|
||||
|
||||
fd_handle_ptr handle = qfs.GetHandle(fd);
|
||||
if (nullptr == handle)
|
||||
return -QUASI_EBADF;
|
||||
|
||||
bool host_used = false;
|
||||
int hio_status = 0;
|
||||
// bool host_used = false;
|
||||
// int hio_status = 0;
|
||||
int vio_status = 0;
|
||||
|
||||
Libraries::Kernel::OrbisKernelStat hio_stat;
|
||||
// Libraries::Kernel::OrbisKernelStat hio_stat;
|
||||
Libraries::Kernel::OrbisKernelStat vio_stat;
|
||||
|
||||
if (handle->IsHostBound()) {
|
||||
int host_fd = handle->host_fd;
|
||||
hio_status = qfs.hio_driver.FStat(host_fd, &hio_stat);
|
||||
host_used = true;
|
||||
}
|
||||
// if (handle->IsHostBound()) {
|
||||
// int host_fd = handle->host_fd;
|
||||
// hio_status = qfs.hio_driver.FStat(host_fd, &hio_stat);
|
||||
// host_used = true;
|
||||
// }
|
||||
|
||||
qfs.vio_driver.SetCtx(nullptr, host_used, handle);
|
||||
qfs.vio_driver.SetCtx(nullptr, false, handle);
|
||||
// qfs.vio_driver.SetCtx(nullptr, host_used, handle);
|
||||
vio_status = qfs.vio_driver.FStat(fd, &vio_stat);
|
||||
qfs.vio_driver.ClearCtx();
|
||||
|
||||
if (host_used) {
|
||||
vio_stat.st_mode = hio_stat.st_mode;
|
||||
vio_stat.st_size = hio_stat.st_size;
|
||||
vio_stat.st_blksize = hio_stat.st_blksize;
|
||||
vio_stat.st_blocks = hio_stat.st_blocks;
|
||||
vio_stat.st_atim.tv_sec = hio_stat.st_atim.tv_sec;
|
||||
vio_stat.st_atim.tv_nsec = hio_stat.st_atim.tv_nsec;
|
||||
vio_stat.st_mtim.tv_sec = hio_stat.st_mtim.tv_sec;
|
||||
vio_stat.st_mtim.tv_nsec = hio_stat.st_mtim.tv_nsec;
|
||||
vio_stat.st_ctim.tv_sec = hio_stat.st_ctim.tv_sec;
|
||||
vio_stat.st_ctim.tv_nsec = hio_stat.st_ctim.tv_nsec;
|
||||
}
|
||||
// if (host_used) {
|
||||
// vio_stat.st_mode = hio_stat.st_mode;
|
||||
// vio_stat.st_size = hio_stat.st_size;
|
||||
// vio_stat.st_blksize = hio_stat.st_blksize;
|
||||
// vio_stat.st_blocks = hio_stat.st_blocks;
|
||||
// vio_stat.st_atim.tv_sec = hio_stat.st_atim.tv_sec;
|
||||
// vio_stat.st_atim.tv_nsec = hio_stat.st_atim.tv_nsec;
|
||||
// vio_stat.st_mtim.tv_sec = hio_stat.st_mtim.tv_sec;
|
||||
// vio_stat.st_mtim.tv_nsec = hio_stat.st_mtim.tv_nsec;
|
||||
// vio_stat.st_ctim.tv_sec = hio_stat.st_ctim.tv_sec;
|
||||
// vio_stat.st_ctim.tv_nsec = hio_stat.st_ctim.tv_nsec;
|
||||
// }
|
||||
|
||||
memcpy(statbuf, &vio_stat, sizeof(Libraries::Kernel::OrbisKernelStat));
|
||||
|
||||
if (host_used && (hio_status != vio_status))
|
||||
LOG_ERROR(Kernel_Fs, "Host returned {}, but virtual driver returned {}", hio_status,
|
||||
vio_status);
|
||||
// if (host_used && (hio_status != vio_status))
|
||||
// LOG_ERROR(Kernel_Fs, "Host returned {}, but virtual driver returned {}", hio_status,
|
||||
// vio_status);
|
||||
|
||||
return vio_status;
|
||||
}
|
||||
@ -840,6 +873,9 @@ s32 QFS::OperationImpl::Chmod(const fs::path& path, u16 mode) {
|
||||
}
|
||||
|
||||
s32 QFS::OperationImpl::FChmod(const s32 fd, u16 mode) {
|
||||
if (fd < 0)
|
||||
return -QUASI_EBADF;
|
||||
|
||||
fd_handle_ptr handle = qfs.GetHandle(fd);
|
||||
if (nullptr == handle)
|
||||
return -QUASI_EBADF;
|
||||
|
||||
@ -27,6 +27,8 @@ enum class SaveDataDialogMode : u32 {
|
||||
};
|
||||
|
||||
// dirty hack
|
||||
// *dows pollutes a lot of defines from winnt.h and wingdi.h
|
||||
// I'm sick and tired of it, so here we are
|
||||
#ifdef DELETE
|
||||
#undef DELETE
|
||||
#endif
|
||||
@ -34,7 +36,6 @@ enum class SaveDataDialogMode : u32 {
|
||||
#undef ERROR
|
||||
#endif
|
||||
|
||||
|
||||
enum class DialogType : u32 {
|
||||
SAVE = 1,
|
||||
LOAD = 2,
|
||||
|
||||
@ -165,9 +165,9 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder) {
|
||||
|
||||
qfs->SyncHost();
|
||||
|
||||
qfs::printTree(qfs->GetRoot(), "/");
|
||||
qfs::printTree(qfs->GetRoot(), "/");
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
void Emulator::Run(std::filesystem::path file, std::vector<std::string> args,
|
||||
@ -421,14 +421,14 @@ void Emulator::Run(std::filesystem::path file, std::vector<std::string> args,
|
||||
|
||||
g_window = window.get();
|
||||
|
||||
// const auto& mount_data_dir = Common::FS::GetUserPath(Common::FS::PathType::GameDataDir) / id;
|
||||
// const auto& mount_data_dir = Common::FS::GetUserPath(Common::FS::PathType::GameDataDir) / id;
|
||||
if (!std::filesystem::exists(mount_data_dir)) {
|
||||
std::filesystem::create_directory(mount_data_dir);
|
||||
}
|
||||
mnt->Mount(mount_data_dir, "/data"); // should just exist, manually create with game serial
|
||||
|
||||
// Mounting temp folders
|
||||
//const auto& mount_temp_dir = Common::FS::GetUserPath(Common::FS::PathType::TempDataDir) / id;
|
||||
// const auto& mount_temp_dir = Common::FS::GetUserPath(Common::FS::PathType::TempDataDir) / id;
|
||||
if (std::filesystem::exists(mount_temp_dir)) {
|
||||
// Temp folder should be cleared on each boot.
|
||||
std::filesystem::remove_all(mount_temp_dir);
|
||||
@ -437,14 +437,15 @@ void Emulator::Run(std::filesystem::path file, std::vector<std::string> args,
|
||||
mnt->Mount(mount_temp_dir, "/temp0");
|
||||
mnt->Mount(mount_temp_dir, "/temp");
|
||||
|
||||
// const auto& mount_download_dir =
|
||||
// Common::FS::GetUserPath(Common::FS::PathType::DownloadDir) / id;
|
||||
// const auto& mount_download_dir =
|
||||
// Common::FS::GetUserPath(Common::FS::PathType::DownloadDir) / id;
|
||||
if (!std::filesystem::exists(mount_download_dir)) {
|
||||
std::filesystem::create_directory(mount_download_dir);
|
||||
}
|
||||
mnt->Mount(mount_download_dir, "/download0");
|
||||
|
||||
// const auto& mount_captures_dir = Common::FS::GetUserPath(Common::FS::PathType::CapturesDir);
|
||||
// const auto& mount_captures_dir =
|
||||
// Common::FS::GetUserPath(Common::FS::PathType::CapturesDir);
|
||||
if (!std::filesystem::exists(mount_captures_dir)) {
|
||||
std::filesystem::create_directory(mount_captures_dir);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user