Implemented sceKernelTruncate (was missing)

Ported /dev devices to QuasiDevice
File modes printed as octal
... and more
This commit is contained in:
Marek Ledworowski 2025-10-20 23:28:54 +02:00
parent b0f31ad23a
commit c16ba68422
34 changed files with 388 additions and 681 deletions

View File

@ -766,22 +766,24 @@ set(CORE src/core/aerolib/stubs.cpp
src/core/aerolib/aerolib.h
src/core/address_space.cpp
src/core/address_space.h
src/core/file_sys/devices/base_device.cpp
src/core/file_sys/devices/base_device.h
src/core/file_sys/devices/ioccom.h
src/core/file_sys/devices/logger.cpp
src/core/file_sys/devices/logger.h
src/core/file_sys/devices/nop_device.h
src/core/file_sys/devices/console_device.cpp
src/core/file_sys/devices/console_device.h
src/core/file_sys/devices/deci_tty6_device.cpp
src/core/file_sys/devices/deci_tty6_device.h
src/core/file_sys/devices/ioccom.h
src/core/file_sys/devices/logger.cpp
src/core/file_sys/devices/logger.h
src/core/file_sys/devices/nop_device.h
src/core/file_sys/devices/random_device.cpp
src/core/file_sys/devices/random_device.h
src/core/file_sys/devices/urandom_device.cpp
src/core/file_sys/devices/urandom_device.h
src/core/file_sys/devices/srandom_device.cpp
src/core/file_sys/devices/srandom_device.h
src/core/file_sys/devices/zero_device.cpp
src/core/file_sys/devices/zero_device.h
src/core/file_sys/directories/base_directory.cpp
src/core/file_sys/directories/base_directory.h
src/core/file_sys/directories/normal_directory.cpp

View File

@ -7,6 +7,17 @@
#include "common/types.h"
#include "common/va_ctx.h"
/**
*
*
*
* TODO: Find a way to yeet this
*
*
*
*
*/
namespace Libraries::Kernel {
struct OrbisKernelStat;
struct OrbisKernelIovec;

View File

@ -1,74 +1,11 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "console_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> ConsoleDevice::Create(u32 handle, const char*, int, u16) {
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new ConsoleDevice(handle)));
}
int ConsoleDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 ConsoleDevice::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t ConsoleDevice::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t ConsoleDevice::readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 ConsoleDevice::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 ConsoleDevice::lseek(s64 offset, int whence) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 ConsoleDevice::read(void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int ConsoleDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s32 ConsoleDevice::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int ConsoleDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int ConsoleDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 ConsoleDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
ConsoleDevice::ConsoleDevice() = default;
ConsoleDevice::~ConsoleDevice() = default;
} // namespace Core::Devices

View File

@ -2,32 +2,33 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include "base_device.h"
#include "core/file_sys/quasifs/quasifs_inode_device.h"
namespace Core::Devices {
class ConsoleDevice final : BaseDevice {
u32 handle;
class ConsoleDevice final : public QuasiFS::Device {
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
explicit ConsoleDevice(u32 handle) : handle(handle) {}
ConsoleDevice();
~ConsoleDevice();
~ConsoleDevice() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
// clang-format off
s64 read(void* buf, u64 count) override { DEVICE_STUB(); };
s64 write(const void* buf, u64 count) override { DEVICE_STUB(); };
s32 ioctl(u64 cmd, Common::VaCtx* args) override { DEVICE_STUB(); };
s64 pread(void* buf, size_t count, u64 offset) override { DEVICE_STUB(); };
s64 pwrite(const void* buf, size_t count, u64 offset) override { DEVICE_STUB(); };
s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override { DEVICE_STUB(); };
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override { DEVICE_STUB(); };
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override { DEVICE_STUB(); };
s64 pwritev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override { DEVICE_STUB(); };
s64 lseek(s64 offset, int whence) override { DEVICE_STUB(); };
s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { DEVICE_STUB(); };
s32 fsync() override { DEVICE_STUB(); };
s32 ftruncate(s64 length) override { DEVICE_STUB(); };
s32 getdents(void* buf, u32 nbytes, s64* basep) override { DEVICE_STUB(); };
// clang-format on
};
} // namespace Core::Devices

View File

@ -1,74 +1,11 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/logging/log.h"
#include "deci_tty6_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> DeciTty6Device::Create(u32 handle, const char*, int, u16) {
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new DeciTty6Device(handle)));
}
int DeciTty6Device::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 DeciTty6Device::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t DeciTty6Device::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t DeciTty6Device::readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 DeciTty6Device::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 DeciTty6Device::lseek(s64 offset, int whence) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 DeciTty6Device::read(void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int DeciTty6Device::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s32 DeciTty6Device::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int DeciTty6Device::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int DeciTty6Device::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 DeciTty6Device::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
DeciTty6Device::DeciTty6Device() = default;
DeciTty6Device::~DeciTty6Device() = default;
} // namespace Core::Devices

View File

@ -3,31 +3,33 @@
#pragma once
#include <memory>
#include "base_device.h"
#include "core/file_sys/quasifs/quasifs_inode_device.h"
namespace Core::Devices {
class DeciTty6Device final : BaseDevice {
u32 handle;
class DeciTty6Device final : public QuasiFS::Device {
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
explicit DeciTty6Device(u32 handle) : handle(handle) {}
DeciTty6Device();
~DeciTty6Device();
~DeciTty6Device() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
// clang-format off
s64 read(void* buf, u64 count) override { DEVICE_STUB(); };
s64 write(const void* buf, u64 count) override { DEVICE_STUB(); };
s32 ioctl(u64 cmd, Common::VaCtx* args) override { DEVICE_STUB(); };
s64 pread(void* buf, size_t count, u64 offset) override { DEVICE_STUB(); };
s64 pwrite(const void* buf, size_t count, u64 offset) override { DEVICE_STUB(); };
s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override { DEVICE_STUB(); };
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override { DEVICE_STUB(); };
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override { DEVICE_STUB(); };
s64 pwritev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override { DEVICE_STUB(); };
s64 lseek(s64 offset, int whence) override { DEVICE_STUB(); };
s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { DEVICE_STUB(); };
s32 fsync() override { DEVICE_STUB(); };
s32 ftruncate(s64 length) override { DEVICE_STUB(); };
s32 getdents(void* buf, u32 nbytes, s64* basep) override { DEVICE_STUB(); };
// clang-format on
};
} // namespace Core::Devices

View File

@ -16,7 +16,12 @@ s64 Logger::write(const void* buf, size_t nbytes) {
return nbytes;
}
size_t Logger::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
s64 Logger::pwrite(const void* buf, size_t nbytes, u64 offset) {
log(static_cast<const char*>(buf), nbytes);
return nbytes;
}
s64 Logger::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
size_t total_written = 0;
for (int i = 0; i < iovcnt; i++) {
log(static_cast<const char*>(iov[i].iov_base), iov[i].iov_len);
@ -25,11 +30,6 @@ size_t Logger::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt
return total_written;
}
s64 Logger::pwrite(const void* buf, size_t nbytes, u64 offset) {
log(static_cast<const char*>(buf), nbytes);
return nbytes;
}
s32 Logger::fsync() {
log_flush();
return 0;

View File

@ -3,15 +3,15 @@
#pragma once
#include "base_device.h"
#include <mutex>
#include <string>
#include <vector>
#include "core/file_sys/quasifs/quasifs_inode_device.h"
namespace Core::Devices {
class Logger final : BaseDevice {
class Logger final : public QuasiFS::Device {
std::string prefix;
bool is_err;
@ -20,12 +20,11 @@ class Logger final : BaseDevice {
public:
explicit Logger(std::string prefix, bool is_err);
~Logger() override;
~Logger();
s64 write(const void* buf, size_t nbytes) override;
size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
s32 fsync() override;

View File

@ -2,65 +2,33 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "base_device.h"
#include "core/file_sys/quasifs/quasifs_inode_device.h"
namespace Core::Devices {
class NopDevice final : BaseDevice {
u32 handle;
class NopDevice final : public QuasiFS::Device {
public:
explicit NopDevice(u32 handle) : handle(handle) {}
NopDevice() = default;
~NopDevice() = default;
~NopDevice() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override {
return 0;
}
s64 write(const void* buf, size_t nbytes) override {
return 0;
}
size_t readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override {
return 0;
}
size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override {
return 0;
}
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override {
return 0;
}
s64 lseek(s64 offset, int whence) override {
return 0;
}
s64 read(void* buf, size_t nbytes) override {
return 0;
}
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override {
return 0;
}
s32 fsync() override {
return 0;
}
int ftruncate(s64 length) override {
return 0;
}
int getdents(void* buf, u32 nbytes, s64* basep) override {
return 0;
}
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override {
return 0;
}
// clang-format off
s64 read(void* buf, u64 count) override { return 0; };
s64 write(const void* buf, u64 count) override { return 0; };
s32 ioctl(u64 cmd, Common::VaCtx* args) override { return 0; };
s64 pread(void* buf, size_t count, u64 offset) override { return 0; };
s64 pwrite(const void* buf, size_t count, u64 offset) override { return 0; };
s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override { return 0; };
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override { return 0; };
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override { return 0; };
s64 pwritev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override { return 0; };
s64 lseek(s64 offset, int whence) override { return 0; };
s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { return 0; };
s32 fsync() override { return 0; };
s32 ftruncate(s64 length) override { return 0; };
s32 getdents(void* buf, u32 nbytes, s64* basep) override { return 0; };
// clang-format on
};
} // namespace Core::Devices

View File

@ -3,77 +3,23 @@
#include <cstdlib>
#include <ctime>
#include "common/logging/log.h"
#include "random_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> RandomDevice::Create(u32 handle, const char*, int, u16) {
RandomDevice::RandomDevice() {
std::srand(std::time(nullptr));
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new RandomDevice(handle)));
}
int RandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
RandomDevice::~RandomDevice() = default;
s64 RandomDevice::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t RandomDevice::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t RandomDevice::readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 RandomDevice::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 RandomDevice::lseek(s64 offset, int whence) {
return 0;
}
s64 RandomDevice::read(void* buf, size_t nbytes) {
s64 RandomDevice::read(void* buf, u64 count) {
auto rbuf = static_cast<char*>(buf);
for (size_t i = 0; i < nbytes; i++) {
for (size_t i = 0; i < count; i++) {
rbuf[i] = std::rand() & 0xFF;
}
return nbytes;
}
int RandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s32 RandomDevice::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int RandomDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int RandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 RandomDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
return count;
}
} // namespace Core::Devices

View File

@ -2,32 +2,35 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include "base_device.h"
#include "core/file_sys/quasifs/quasifs_inode_device.h"
namespace Core::Devices {
class RandomDevice final : BaseDevice {
u32 handle;
class RandomDevice final : public QuasiFS::Device {
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
explicit RandomDevice(u32 handle) : handle(handle) {}
RandomDevice();
~RandomDevice();
~RandomDevice() override = default;
s64 read(void* buf, u64 count) override;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
// clang-format off
s64 write(const void* buf, u64 count) override { DEVICE_STUB(); }
s32 ioctl(u64 cmd, Common::VaCtx* args) override { DEVICE_STUB(); }
s64 pread(void* buf, size_t count, u64 offset) override { DEVICE_STUB(); }
s64 pwrite(const void* buf, size_t count, u64 offset) override { DEVICE_STUB(); }
s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override { DEVICE_STUB(); }
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override { DEVICE_STUB(); }
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override { DEVICE_STUB(); }
s64 pwritev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override { DEVICE_STUB(); }
s64 lseek(s64 offset, int whence) override { DEVICE_STUB(); }
s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { DEVICE_STUB(); }
s32 fsync() override { DEVICE_STUB(); }
s32 ftruncate(s64 length) override { DEVICE_STUB(); }
s32 getdents(void* buf, u32 nbytes, s64* basep) override { DEVICE_STUB(); }
// clang-format on
};
} // namespace Core::Devices

View File

@ -3,78 +3,23 @@
#include <cstdlib>
#include <ctime>
#include "common/logging/log.h"
#include "srandom_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> SRandomDevice::Create(u32 handle, const char*, int, u16) {
SRandomDevice::SRandomDevice() {
std::srand(std::time(nullptr));
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new SRandomDevice(handle)));
}
int SRandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
SRandomDevice::~SRandomDevice() = default;
s64 SRandomDevice::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t SRandomDevice::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t SRandomDevice::readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 SRandomDevice::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 SRandomDevice::lseek(s64 offset, int whence) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 SRandomDevice::read(void* buf, size_t nbytes) {
s64 SRandomDevice::read(void* buf, u64 count) {
auto rbuf = static_cast<char*>(buf);
for (size_t i = 0; i < nbytes; i++) {
for (size_t i = 0; i < count; i++) {
rbuf[i] = std::rand();
}
return nbytes;
}
int SRandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s32 SRandomDevice::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return s32();
}
int SRandomDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int SRandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 SRandomDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
return count;
}
} // namespace Core::Devices

View File

@ -2,32 +2,36 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include "base_device.h"
#include "core/file_sys/quasifs/quasifs_inode_device.h"
namespace Core::Devices {
class SRandomDevice final : BaseDevice {
u32 handle;
class SRandomDevice final : public QuasiFS::Device {
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
explicit SRandomDevice(u32 handle) : handle(handle) {}
SRandomDevice();
~SRandomDevice();
~SRandomDevice() override = default;
s64 read(void* buf, u64 count) override;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
// clang-format off
s64 write(const void* buf, u64 count) override { DEVICE_STUB(); }
s32 ioctl(u64 cmd, Common::VaCtx* args) override { DEVICE_STUB(); }
s64 pread(void* buf, size_t count, u64 offset) override { DEVICE_STUB(); }
s64 pwrite(const void* buf, size_t count, u64 offset) override { DEVICE_STUB(); }
s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override { DEVICE_STUB(); }
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override { DEVICE_STUB(); }
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override { DEVICE_STUB(); }
s64 pwritev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override { DEVICE_STUB(); }
s64 lseek(s64 offset, int whence) override { DEVICE_STUB(); }
s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { DEVICE_STUB(); }
s32 fsync() override { DEVICE_STUB(); }
s32 ftruncate(s64 length) override { DEVICE_STUB(); }
s32 getdents(void* buf, u32 nbytes, s64* basep) override { DEVICE_STUB(); }
// clang-format on
};
} // namespace Core::Devices

View File

@ -1,19 +0,0 @@
#include "core/file_sys/devices/logger.h"
#include "core/file_sys/quasifs/quasifs_inode_device.h"
class std_device : public QuasiFS::Device {
private:
Core::Devices::Logger* logger;
public:
std_device(std::string name, bool is_err) {
this->logger = new Core::Devices::Logger(name, is_err);
}
~std_device() {
delete logger;
}
virtual s64 pwrite(const void* buf, size_t count, u64 offset) override {
return logger->write(buf, count);
}
};

View File

@ -1,80 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <cstdlib>
#include <ctime>
#include "common/logging/log.h"
#include "urandom_device.h"
namespace Core::Devices {
std::shared_ptr<BaseDevice> URandomDevice::Create(u32 handle, const char*, int, u16) {
std::srand(std::time(nullptr));
return std::shared_ptr<BaseDevice>(
reinterpret_cast<Devices::BaseDevice*>(new URandomDevice(handle)));
}
int URandomDevice::ioctl(u64 cmd, Common::VaCtx* args) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 URandomDevice::write(const void* buf, size_t nbytes) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t URandomDevice::writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
size_t URandomDevice::readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 URandomDevice::preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 URandomDevice::lseek(s64 offset, int whence) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 URandomDevice::read(void* buf, size_t nbytes) {
auto rbuf = static_cast<char*>(buf);
for (size_t i = 0; i < nbytes; i++) {
rbuf[i] = std::rand() & 0xFF;
}
return nbytes;
}
int URandomDevice::fstat(Libraries::Kernel::OrbisKernelStat* sb) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s32 URandomDevice::fsync() {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int URandomDevice::ftruncate(s64 length) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
int URandomDevice::getdents(void* buf, u32 nbytes, s64* basep) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
s64 URandomDevice::pwrite(const void* buf, size_t nbytes, u64 offset) {
LOG_ERROR(Kernel_Pthread, "(STUBBED) called");
return 0;
}
} // namespace Core::Devices

View File

@ -1,33 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include "base_device.h"
namespace Core::Devices {
class URandomDevice final : BaseDevice {
u32 handle;
public:
static std::shared_ptr<BaseDevice> Create(u32 handle, const char*, int, u16);
explicit URandomDevice(u32 handle) : handle(handle) {}
~URandomDevice() override = default;
int ioctl(u64 cmd, Common::VaCtx* args) override;
s64 write(const void* buf, size_t nbytes) override;
size_t readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
size_t writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override;
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override;
s64 lseek(s64 offset, int whence) override;
s64 read(void* buf, size_t nbytes) override;
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override;
s32 fsync() override;
int ftruncate(s64 length) override;
int getdents(void* buf, u32 nbytes, s64* basep) override;
s64 pwrite(const void* buf, size_t nbytes, u64 offset) override;
};
} // namespace Core::Devices

View File

@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <cstring>
#include "zero_device.h"
namespace Core::Devices {
ZeroDevice::ZeroDevice() = default;
ZeroDevice::~ZeroDevice() = default;
s64 ZeroDevice::read(void* buf, u64 count) {
memset(buf, 0, count);
return count;
}
s64 ZeroDevice::write(const void* buf, u64 count) {
return count;
}
s64 ZeroDevice::pread(void* buf, size_t count, u64 offset) {
memset(buf, 0, count);
return count;
}
s64 ZeroDevice::pwrite(const void* buf, size_t count, u64 offset) {
return count;
}
} // namespace Core::Devices

View File

@ -1,19 +1,37 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <cstring>
#include "core/file_sys/quasifs/quasifs_inode_device.h"
class zero_device : public QuasiFS::Device {
namespace Core::Devices {
class ZeroDevice final : public QuasiFS::Device {
public:
zero_device() = default;
~zero_device() = default;
ZeroDevice();
~ZeroDevice();
virtual s64 read(u64 offset, void* buf, u64 count) {
memset(buf, 0, count);
return count;
}
s64 read(void* buf, u64 count) override;
s64 write(const void* buf, u64 count) override;
s64 pread(void* buf, size_t count, u64 offset) override;
s64 pwrite(const void* buf, size_t count, u64 offset) override;
virtual s64 write(u64 offset, const void* buf, u64 count) {
return count;
}
// clang-format off
s32 ioctl(u64 cmd, Common::VaCtx* args) override { DEVICE_STUB(); }
s64 readv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override { DEVICE_STUB(); }
s64 writev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt) override { DEVICE_STUB(); }
s64 preadv(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override { DEVICE_STUB(); }
s64 pwritev(const Libraries::Kernel::OrbisKernelIovec* iov, int iovcnt, u64 offset) override { DEVICE_STUB(); }
s64 lseek(s64 offset, int whence) override { DEVICE_STUB(); }
s32 fstat(Libraries::Kernel::OrbisKernelStat* sb) override { DEVICE_STUB(); }
s32 fsync() override { DEVICE_STUB(); }
s32 ftruncate(s64 length) override { DEVICE_STUB(); }
s32 getdents(void* buf, u32 nbytes, s64* basep) override { DEVICE_STUB(); }
// clang-format on
};
} // namespace Core::Devices

View File

@ -41,31 +41,31 @@ public:
static constexpr int ToPOSIXOpenFlags(int quasi_flags) {
int flags = 0;
if (quasi_flags | QUASI_O_RDONLY)
if (quasi_flags & QUASI_O_RDONLY)
flags |= O_RDONLY;
if (quasi_flags | QUASI_O_WRONLY)
if (quasi_flags & QUASI_O_WRONLY)
flags |= O_WRONLY;
if (quasi_flags | QUASI_O_RDWR)
if (quasi_flags & QUASI_O_RDWR)
flags |= O_RDWR;
if (quasi_flags | QUASI_O_CREAT)
if (quasi_flags & QUASI_O_CREAT)
flags |= O_CREAT;
if (quasi_flags | QUASI_O_EXCL)
if (quasi_flags & QUASI_O_EXCL)
flags |= O_EXCL;
if (quasi_flags | QUASI_O_TRUNC)
if (quasi_flags & QUASI_O_TRUNC)
flags |= O_TRUNC;
if (quasi_flags | QUASI_O_APPEND)
if (quasi_flags & QUASI_O_APPEND)
flags |= O_APPEND;
if (quasi_flags | QUASI_O_NONBLOCK)
if (quasi_flags & QUASI_O_NONBLOCK)
flags |= O_NONBLOCK;
if (quasi_flags | QUASI_O_SYNC)
if (quasi_flags & QUASI_O_SYNC)
flags |= O_SYNC;
if (quasi_flags | QUASI_O_FSYNC)
if (quasi_flags & QUASI_O_FSYNC)
flags |= O_FSYNC;
if (quasi_flags | QUASI_O_DIRECTORY)
if (quasi_flags & QUASI_O_DIRECTORY)
flags |= O_DIRECTORY;
if (quasi_flags | QUASI_O_DIRECT)
if (quasi_flags & QUASI_O_DIRECT)
flags |= O_DIRECT;
if (quasi_flags | QUASI_O_DSYNC)
if (quasi_flags & QUASI_O_DSYNC)
flags |= O_DSYNC;
return flags;

View File

@ -139,14 +139,16 @@ int HostIO_POSIX::Stat(const fs::path& path, Libraries::Kernel::OrbisKernelStat*
// statbuf->st_ino = st.st_ino;
// statbuf->st_nlink = st.st_nlink;
// TODO: make working
// statbuf->st_mode = st.st_mode;
// statbuf->st_size = st.st_size;
// statbuf->st_blksize = st.st_blksize;
// statbuf->st_blocks = st.st_blocks;
// statbuf->st_atim = st.st_atim;
// statbuf->st_mtim = st.st_mtim;
// statbuf->st_ctim = st.st_ctim;
statbuf->st_mode = st.st_mode;
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;
return 0;
}

View File

@ -4,6 +4,8 @@
#include <unordered_map>
#include "common/types.h"
#include "quasi_errno.h"
#include "quasi_types.h"
#include "quasifs_inode.h"
@ -58,28 +60,28 @@ private:
OperationImpl(QFS& qfs) : qfs(qfs) {}
int Open(const fs::path& path, int flags, u16 mode = 0755) override;
int Creat(const fs::path& path, u16 mode = 0755) override;
int Close(const int fd) override;
int Close(const s32 fd) override;
int LinkSymbolic(const fs::path& src, const fs::path& dst) override;
int Link(const fs::path& src, const fs::path& dst) override;
int Unlink(const fs::path& path) override;
int Flush(const int fd) override;
int FSync(const int fd) override;
int Flush(const s32 fd) override;
int FSync(const s32 fd) override;
int Truncate(const fs::path& path, u64 size) override;
int FTruncate(const int fd, u64 size) override;
u64 LSeek(const int fd, u64 offset, SeekOrigin origin) override;
s64 Tell(const int fd) override;
s64 Write(const int fd, const void* buf, u64 count) override;
s64 PWrite(const int fd, const void* buf, u64 count, u64 offset) override;
s64 Read(const int fd, void* buf, u64 count) override;
s64 PRead(const int fd, void* buf, u64 count, u64 offset) override;
int FTruncate(const s32 fd, u64 size) override;
u64 LSeek(const s32 fd, u64 offset, SeekOrigin origin) override;
s64 Tell(const s32 fd) override;
s64 Write(const s32 fd, const void* buf, u64 count) override;
s64 PWrite(const s32 fd, const void* buf, u64 count, u64 offset) override;
s64 Read(const s32 fd, void* buf, u64 count) override;
s64 PRead(const s32 fd, void* buf, u64 count, u64 offset) override;
int MKDir(const fs::path& path, u16 mode = 0755) override;
int RMDir(const fs::path& path) override;
int Stat(const fs::path& path, Libraries::Kernel::OrbisKernelStat* statbuf) override;
int FStat(const int fd, Libraries::Kernel::OrbisKernelStat* statbuf) override;
int FStat(const s32 fd, Libraries::Kernel::OrbisKernelStat* statbuf) override;
int Chmod(const fs::path& path, u16 mode) override;
int FChmod(const int fd, u16 mode) override;
int FChmod(const s32 fd, u16 mode) override;
};
public:
@ -150,9 +152,9 @@ public:
// Additional binds
//
bool IsOpen(const int fd) noexcept;
int SetSize(const int fd, uint64_t size) noexcept;
s64 GetSize(const int fd) noexcept;
bool IsOpen(const s32 fd) noexcept;
int SetSize(const s32 fd, uint64_t size) noexcept;
s64 GetSize(const s32 fd) noexcept;
// Not a port, used by 2-3 functions that ;
s64 GetDirectorySize(const fs::path& path) noexcept;
@ -232,7 +234,7 @@ private:
// Get next available fd slot
int GetFreeHandleNo();
fd_handle_ptr GetHandle(int fd);
fd_handle_ptr GetHandle(s32 fd);
// partition by blkdev
// partition_ptr GetPartitionByBlockdev(uint64_t blkid);
mount_t* GetPartitionInfo(const partition_ptr part);

View File

@ -16,17 +16,25 @@ namespace QuasiFS {
class Inode {
public:
Inode() = default;
virtual ~Inode() = default;
static inode_ptr Create(void) {
return std::make_shared<Inode>();
Inode() {
st.st_mode = 0000755;
st.st_nlink = 0;
}
virtual ~Inode() = default;
virtual s32 ioctl(u64 cmd, Common::VaCtx* args) {
return -QUASI_ENOTTY;
}
virtual s64 read(void* buf, size_t count) {
return -QUASI_EBADF;
}
virtual s64 write(const void* buf, size_t count) {
return -QUASI_EBADF;
}
virtual s64 pread(void* buf, size_t count, u64 offset) {
return -QUASI_EBADF;
}

View File

@ -2,16 +2,32 @@
#pragma once
#include "common/assert.h"
#include "common/logging/log.h"
#include "quasi_types.h"
#include "quasifs_inode.h"
#define DEVICE_STUB() \
{ \
LOG_ERROR(Kernel_Fs, "(STUBBED) called"); \
return 0; \
}
namespace QuasiFS {
class Device : public Inode {
public:
Device();
~Device() = default;
~Device();
template <typename T, typename... Args>
static dev_ptr Create(Args&&... args) {
if constexpr (std::is_base_of_v<Device, T>)
return std::make_shared<T>(std::forward<Args>(args)...);
UNREACHABLE();
}
};
} // namespace QuasiFS

View File

@ -30,7 +30,7 @@ public:
// s64 pread(void* buf, size_t count, u64 offset) override;
// s64 pwrite(const void* buf, size_t count, u64 offset) override;
virtual int fstat(Libraries::Kernel::OrbisKernelStat* sb) override {
int fstat(Libraries::Kernel::OrbisKernelStat* sb) override {
this->st.st_size = entries.size() * 32;
*sb = st;
return 0;

View File

@ -7,7 +7,7 @@
namespace QuasiFS {
class RegularFile : public Inode {
class RegularFile final : public Inode {
std::vector<char> data{};
public:
@ -21,6 +21,8 @@ public:
//
// Working functions
//
s64 read(void* buf, size_t count) override;
s64 write(const void* buf, size_t count) override;
s64 pread(void* buf, size_t count, u64 offset) override;
s64 pwrite(const void* buf, size_t count, u64 offset) override;
s32 ftruncate(s64 length) override;

View File

@ -7,7 +7,7 @@
namespace QuasiFS {
class Symlink : public Inode {
class Symlink final : public Inode {
const fs::path target;
public:

View File

@ -10,9 +10,9 @@ Device::Device() {
this->st.st_blksize = 0;
this->st.st_blocks = 0;
this->st.st_mode = 0000755 | QUASI_S_IFCHR;
this->st.st_nlink = 0;
// not incrementing target, this type is a softlink
this->st.st_mode |= QUASI_S_IFCHR;
}
Device::~Device() = default;
} // namespace QuasiFS

View File

@ -9,8 +9,7 @@
namespace QuasiFS {
Directory::Directory() {
st.st_mode = 0000755 | QUASI_S_IFDIR;
st.st_nlink = 0;
st.st_mode |= QUASI_S_IFDIR;
}
inode_ptr Directory::lookup(const std::string& name) {

View File

@ -12,6 +12,14 @@ RegularFile::RegularFile() {
st.st_nlink = 0;
}
s64 RegularFile::read(void* buf, size_t count) {
return pread(buf, count, 0);
}
s64 RegularFile::write(const void* buf, size_t count) {
return pwrite(buf, count, 0);
}
s64 RegularFile::pread(void* buf, size_t count, u64 offset) {
s64 idx;
u64 read_amt = this->data.size() - offset - count;

View File

@ -7,8 +7,7 @@ namespace QuasiFS {
Symlink::Symlink(fs::path target) : target(target) {
// fileno and blkdev assigned by partition
this->st.st_size = target.string().size();
this->st.st_mode = 0000755 | QUASI_S_IFLNK;
this->st.st_nlink = 0;
this->st.st_mode |= QUASI_S_IFLNK;
// not incrementing target, this type is a softlink
}

View File

@ -31,8 +31,8 @@ int QFS::OperationImpl::Open(const fs::path& path, int flags, u16 mode) {
partition_ptr part = res.mountpoint;
dir_ptr parent_node = std::static_pointer_cast<Directory>(res.parent);
bool request_read = !(flags & QUASI_O_WRONLY) | QUASI_O_RDWR;
bool request_write = flags & (QUASI_O_WRONLY | QUASI_O_RDWR);
bool request_read = (flags & (QUASI_O_WRONLY | QUASI_O_RDWR)) == 0;
bool request_write = (flags & (QUASI_O_WRONLY | QUASI_O_RDWR)) != 0;
bool request_append = flags & QUASI_O_APPEND;
//
@ -49,6 +49,9 @@ int QFS::OperationImpl::Open(const fs::path& path, int flags, u16 mode) {
if ((request_read && !checked_node->CanRead()) || (request_write && !checked_node->CanWrite()))
return -QUASI_EACCES;
if ((flags & (QUASI_O_WRONLY | QUASI_O_RDWR)) == (QUASI_O_WRONLY | QUASI_O_RDWR))
return -QUASI_EINVAL;
//
// Proceed
//
@ -98,7 +101,7 @@ int QFS::OperationImpl::Creat(const fs::path& path, u16 mode) {
return Open(path, QUASI_O_CREAT | QUASI_O_WRONLY | QUASI_O_TRUNC, mode);
};
int QFS::OperationImpl::Close(int fd) {
int QFS::OperationImpl::Close(s32 fd) {
fd_handle_ptr handle = qfs.GetHandle(fd);
if (nullptr == handle)
return -QUASI_EBADF;
@ -297,7 +300,7 @@ int QFS::OperationImpl::Unlink(const fs::path& path) {
return vio_status;
}
int QFS::OperationImpl::Flush(const int fd) {
int QFS::OperationImpl::Flush(const s32 fd) {
fd_handle_ptr handle = qfs.GetHandle(fd);
if (nullptr == handle)
return -QUASI_EBADF;
@ -327,7 +330,7 @@ int QFS::OperationImpl::Flush(const int fd) {
return vio_status;
}
int QFS::OperationImpl::FSync(const int fd) {
int QFS::OperationImpl::FSync(const s32 fd) {
fd_handle_ptr handle = qfs.GetHandle(fd);
if (nullptr == handle)
return -QUASI_EBADF;
@ -393,7 +396,7 @@ int QFS::OperationImpl::Truncate(const fs::path& path, u64 length) {
return vio_status;
}
int QFS::OperationImpl::FTruncate(const int fd, u64 length) {
int QFS::OperationImpl::FTruncate(const s32 fd, u64 length) {
fd_handle_ptr handle = qfs.GetHandle(fd);
if (nullptr == handle)
return -QUASI_EBADF;
@ -425,7 +428,7 @@ int QFS::OperationImpl::FTruncate(const int fd, u64 length) {
return vio_status;
}
u64 QFS::OperationImpl::LSeek(const int fd, u64 offset, SeekOrigin origin) {
u64 QFS::OperationImpl::LSeek(const s32 fd, u64 offset, SeekOrigin origin) {
fd_handle_ptr handle = qfs.GetHandle(fd);
if (nullptr == handle)
return -QUASI_EBADF;
@ -452,7 +455,7 @@ u64 QFS::OperationImpl::LSeek(const int fd, u64 offset, SeekOrigin origin) {
return vio_status;
};
s64 QFS::OperationImpl::Tell(int fd) {
s64 QFS::OperationImpl::Tell(s32 fd) {
return LSeek(fd, 0, SeekOrigin::CURRENT);
};
@ -466,7 +469,7 @@ void UpdateStatFromHost(Libraries::Kernel::OrbisKernelStat* vfs,
vfs->st_ctim = host->st_ctim;
}
s64 QFS::OperationImpl::Write(const int fd, const void* buf, u64 count) {
s64 QFS::OperationImpl::Write(const s32 fd, const void* buf, u64 count) {
fd_handle_ptr handle = qfs.GetHandle(fd);
if (nullptr == handle)
return -QUASI_EBADF;
@ -496,7 +499,7 @@ s64 QFS::OperationImpl::Write(const int fd, const void* buf, u64 count) {
return vio_status;
}
s64 QFS::OperationImpl::PWrite(const int fd, const void* buf, u64 count, u64 offset) {
s64 QFS::OperationImpl::PWrite(const s32 fd, const void* buf, u64 count, u64 offset) {
fd_handle_ptr handle = qfs.GetHandle(fd);
if (nullptr == handle)
return -QUASI_EBADF;
@ -526,7 +529,7 @@ s64 QFS::OperationImpl::PWrite(const int fd, const void* buf, u64 count, u64 off
return vio_status;
};
s64 QFS::OperationImpl::Read(const int fd, void* buf, u64 count) {
s64 QFS::OperationImpl::Read(const s32 fd, void* buf, u64 count) {
fd_handle_ptr handle = qfs.GetHandle(fd);
if (nullptr == handle)
return -QUASI_EBADF;
@ -553,10 +556,11 @@ s64 QFS::OperationImpl::Read(const int fd, void* buf, u64 count) {
if (host_used && (hio_status != vio_status))
LogError("Host returned {}, but virtual driver returned {}", hio_status, vio_status);
return vio_status;
return hio_status;
// return vio_status;
}
s64 QFS::OperationImpl::PRead(const int fd, void* buf, u64 count, u64 offset) {
s64 QFS::OperationImpl::PRead(const s32 fd, void* buf, u64 count, u64 offset) {
fd_handle_ptr handle = qfs.GetHandle(fd);
if (nullptr == handle)
return -QUASI_EBADF;
@ -716,7 +720,7 @@ int QFS::OperationImpl::Stat(const fs::path& path, Libraries::Kernel::OrbisKerne
return vio_status;
}
int QFS::OperationImpl::FStat(const int fd, Libraries::Kernel::OrbisKernelStat* statbuf) {
int QFS::OperationImpl::FStat(const s32 fd, Libraries::Kernel::OrbisKernelStat* statbuf) {
fd_handle_ptr handle = qfs.GetHandle(fd);
if (nullptr == handle)
return -QUASI_EBADF;
@ -793,7 +797,7 @@ int QFS::OperationImpl::Chmod(const fs::path& path, u16 mode) {
return vio_status;
}
int QFS::OperationImpl::FChmod(const int fd, u16 mode) {
int QFS::OperationImpl::FChmod(const s32 fd, u16 mode) {
fd_handle_ptr handle = qfs.GetHandle(fd);
if (nullptr == handle)
return -QUASI_EBADF;

View File

@ -97,8 +97,8 @@ public:
// audio queue stalling, which may happen during device changes, for example.
// Otherwise, latency may grow over time unbounded.
if (const auto queued = SDL_GetAudioStreamQueued(stream); queued >= queue_threshold) {
LOG_INFO(Lib_AudioOut, "SDL audio queue backed up ({} queued, {} threshold), clearing.",
queued, queue_threshold);
// LOG_INFO(Lib_AudioOut, "SDL audio queue backed up ({} queued, {} threshold), clearing.",
// queued, queue_threshold);
SDL_ClearAudioStream(stream);
// Recalculate the threshold in case this happened because of a device change.
CalculateQueueThreshold();

View File

@ -9,13 +9,6 @@
#include "common/logging/log.h"
#include "common/scope_exit.h"
#include "common/singleton.h"
#include "core/file_sys/devices/console_device.h"
#include "core/file_sys/devices/deci_tty6_device.h"
#include "core/file_sys/devices/logger.h"
#include "core/file_sys/devices/nop_device.h"
#include "core/file_sys/devices/random_device.h"
#include "core/file_sys/devices/srandom_device.h"
#include "core/file_sys/devices/urandom_device.h"
#include "core/file_sys/directories/normal_directory.h"
#include "core/file_sys/directories/pfs_directory.h"
#include "core/file_sys/fs.h"
@ -41,28 +34,23 @@ namespace qfs = QuasiFS;
static QuasiFS::QFS* g_qfs = Common::Singleton<QuasiFS::QFS>::Instance();
using FactoryDevice = std::function<std::shared_ptr<D::BaseDevice>(u32, const char*, int, u16)>;
// #define GET_DEVICE_FD(fd) \
// [](u32, const char*, int, u16) { \
// return Common::Singleton<Core::FileSys::HandleTable>::Instance()->GetFile(fd)->device; \
// }
#define GET_DEVICE_FD(fd) \
[](u32, const char*, int, u16) { \
return Common::Singleton<Core::FileSys::HandleTable>::Instance()->GetFile(fd)->device; \
}
// prefix path, only dev devices
static std::map<std::string, FactoryDevice> available_device = {
// clang-format off
{"/dev/urandom", &D::URandomDevice::Create },
{"/dev/random", &D::RandomDevice::Create },
{"/dev/srandom", &D::SRandomDevice::Create },
{"/dev/console", &D::ConsoleDevice::Create },
{"/dev/deci_tty6",&D::DeciTty6Device::Create }
// clang-format on
};
// // prefix path, only dev devices
// static std::map<std::string, FactoryDevice> available_device = {
// // clang-format off
// {"/dev/console", &D::ConsoleDevice::Create },
// {"/dev/deci_tty6",&D::DeciTty6Device::Create }
// // clang-format on
// };
namespace Libraries::Kernel {
s32 PS4_SYSV_ABI open(const char* raw_path, s32 flags, u16 mode) {
LOG_INFO(Kernel_Fs, "path = {} flags = {:#x} mode = {}", raw_path, flags, mode);
LOG_INFO(Kernel_Fs, "path = {} flags = {:#x} mode = {:#o}", raw_path, flags, mode);
int result = g_qfs->Operation.Open(raw_path, flags, mode);
if (result < 0)
@ -281,7 +269,7 @@ s64 PS4_SYSV_ABI sceKernelRead(s32 fd, void* buf, u64 nbytes) {
}
s32 PS4_SYSV_ABI posix_mkdir(const char* path, u16 mode) {
LOG_INFO(Kernel_Fs, "path = {} mode = {}", path, mode);
LOG_INFO(Kernel_Fs, "path = {} mode = {:#o}", path, mode);
int result = g_qfs->Operation.MKDir(path, mode);
if (result < 0)
*__Error() = -result;
@ -323,31 +311,12 @@ s32 PS4_SYSV_ABI sceKernelRmdir(const char* path) {
s32 PS4_SYSV_ABI posix_stat(const char* path, OrbisKernelStat* sb) {
LOG_DEBUG(Kernel_Fs, "(PARTIAL) path = {}", path);
Libraries::Kernel::OrbisKernelStat st;
int result = g_qfs->Operation.Stat(path, &st);
int result = g_qfs->Operation.Stat(path, sb);
if (result < 0) {
*__Error() = -result;
return -1;
}
sb->st_dev = st.st_dev;
sb->st_ino = st.st_ino;
sb->st_mode = st.st_mode;
sb->st_nlink = st.st_nlink;
// sb->st_uid = st.st_uid;
// sb->st_gid = st.st_gid;
// sb-> st_rdev=st.st_
// sb->st_atim = st.st_atim;
// sb->st_mtim = st.st_mtim;
// sb-> st_ctim=st.st_
sb->st_size = st.st_size;
sb->st_blocks = st.st_blocks;
sb->st_blksize = st.st_blksize;
// sb->st_flags = st.st_flags;
// sb-> st_gen=st.st_
// sb-> st_lspare=st.st_
// OrbisKernelTimespec st_birthtim;
return ORBIS_OK;
// const auto path_name = mnt->GetHostPath(path);
@ -385,18 +354,12 @@ s32 PS4_SYSV_ABI sceKernelStat(const char* path, OrbisKernelStat* sb) {
}
s32 PS4_SYSV_ABI sceKernelCheckReachability(const char* path) {
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
std::string_view guest_path{path};
for (const auto& prefix : available_device | std::views::keys) {
if (guest_path.starts_with(prefix)) {
return ORBIS_OK;
}
QuasiFS::Resolved res;
if (int result = g_qfs->Resolve(path, res); result != 0) {
*__Error() = -result;
return ErrnoToSceKernelError(*__Error());
}
if (!g_qfs->Exists(guest_path)) {
return ORBIS_KERNEL_ERROR_ENOENT;
}
return ORBIS_OK;
}
@ -461,6 +424,22 @@ s32 PS4_SYSV_ABI sceKernelFtruncate(s32 fd, s64 length) {
return result;
}
s32 PS4_SYSV_ABI posix_truncate(const char* path, s64 length) {
int result = g_qfs->Operation.Truncate(path, length);
if (result < 0)
*__Error() = -result;
return result;
}
s32 PS4_SYSV_ABI sceKernelTruncate(const char* path, s64 length) {
s32 result = posix_truncate(path, length);
if (result < 0) {
LOG_ERROR(Kernel_Fs, "error = {}", *__Error());
return ErrnoToSceKernelError(*__Error());
}
return result;
}
s32 PS4_SYSV_ABI posix_rename(const char* from, const char* to) {
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
bool ro = false;
@ -1081,6 +1060,7 @@ void RegisterFileSystem(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("kBwCPsYX-m4", "libkernel", 1, "libkernel", sceKernelFstat);
LIB_FUNCTION("ih4CD9-gghM", "libkernel", 1, "libkernel", posix_ftruncate);
LIB_FUNCTION("VW3TVZiM4-E", "libkernel", 1, "libkernel", sceKernelFtruncate);
LIB_FUNCTION("WlyEA-sLDf0", "libkernel", 1, "libkernel", sceKernelTruncate);
LIB_FUNCTION("NN01qLRhiqU", "libScePosix", 1, "libkernel", posix_rename);
LIB_FUNCTION("NN01qLRhiqU", "libkernel", 1, "libkernel", posix_rename);
LIB_FUNCTION("52NcYU9+lEo", "libkernel", 1, "libkernel", sceKernelRename);

View File

@ -47,7 +47,13 @@
#include "core/file_sys/quasifs/quasifs.h"
#include "core/file_sys/quasifs/quasifs_inode_device.h"
#include "core/file_sys/quasifs/quasifs_partition.h"
#include "core/file_sys/devices/std_device.h"
#include "core/file_sys/devices/console_device.h"
#include "core/file_sys/devices/deci_tty6_device.h"
#include "core/file_sys/devices/logger.h"
#include "core/file_sys/devices/nop_device.h"
#include "core/file_sys/devices/random_device.h"
#include "core/file_sys/devices/srandom_device.h"
#include "core/file_sys/devices/zero_device.h"
Frontend::WindowSDL* g_window = nullptr;
@ -66,7 +72,6 @@ Emulator::Emulator() {
#endif
}
Emulator::~Emulator() {}
void Emulator::LoadFilesystem(const std::filesystem::path& game_folder, const std::string& id) {
@ -109,8 +114,8 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder, const st
qfs->Mount("/data", partition_data, QuasiFS::MountOptions::MOUNT_RW);
qfs->Mount("/dev", partition_dev, QuasiFS::MountOptions::MOUNT_RW);
qfs->Mount("/download0", partition_download, QuasiFS::MountOptions::MOUNT_RW);
qfs->Mount("/hostapp", partition_hostapp,
QuasiFS::MountOptions::MOUNT_NOOPT | QuasiFS::MountOptions::MOUNT_BIND);
//qfs->Mount("/hostapp", partition_hostapp,
// QuasiFS::MountOptions::MOUNT_NOOPT | QuasiFS::MountOptions::MOUNT_BIND);
qfs->Mount("/temp", partition_temp, QuasiFS::MountOptions::MOUNT_RW);
qfs->Mount("/temp0", partition_temp,
QuasiFS::MountOptions::MOUNT_RW | QuasiFS::MountOptions::MOUNT_BIND);
@ -120,23 +125,31 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder, const st
//
qfs->Operation.MKDir("/dev/fd");
qfs->ForceInsert("/dev/fd", "0", std::make_shared<std_device>("stdin", false));
qfs->ForceInsert("/dev/fd", "1", std::make_shared<std_device>("stdout", false));
qfs->ForceInsert("/dev/fd", "2", std::make_shared<std_device>("stderr", true));
qfs->Operation.Link("/dev/fd/0", "/dev/stdin");
qfs->Operation.Link("/dev/fd/1", "/dev/stdout");
qfs->Operation.Link("/dev/fd/2", "/dev/stderr");
qfs->Operation.Link("/dev/fd/0", "/dev/deci_stdin");
qfs->Operation.Link("/dev/fd/1", "/dev/deci_stdout");
qfs->Operation.Link("/dev/fd/2", "/dev/deci_stderr");
qfs->ForceInsert("/dev", "zero", std::make_shared<zero_device>());
qfs->ForceInsert("/dev/fd", "0", QuasiFS::Device::Create<Devices::NopDevice>());
qfs->ForceInsert("/dev/fd", "1", QuasiFS::Device::Create<Devices::Logger>("stdout", false));
// qfs->ForceInsert("/dev/fd", "1", std::make_shared<Devices::Logger>("stdout", false));
qfs->ForceInsert("/dev/fd", "2", QuasiFS::Device::Create<Devices::Logger>("stderr", true));
qfs->Operation.LinkSymbolic("/dev/fd/0", "/dev/stdin");
qfs->Operation.LinkSymbolic("/dev/fd/1", "/dev/stdout");
qfs->Operation.LinkSymbolic("/dev/fd/2", "/dev/stderr");
qfs->Operation.LinkSymbolic("/dev/fd/0", "/dev/deci_stdin");
qfs->Operation.LinkSymbolic("/dev/fd/1", "/dev/deci_stdout");
qfs->Operation.LinkSymbolic("/dev/fd/2", "/dev/deci_stderr");
qfs->ForceInsert("/dev", "console", QuasiFS::Device::Create<Devices::ConsoleDevice>());
qfs->ForceInsert("/dev", "deci_tty6", QuasiFS::Device::Create<Devices::DeciTty6Device>());
qfs->ForceInsert("/dev", "random", QuasiFS::Device::Create<Devices::RandomDevice>());
qfs->ForceInsert("/dev", "urandom", QuasiFS::Device::Create<Devices::RandomDevice>());
qfs->ForceInsert("/dev", "srandom", QuasiFS::Device::Create<Devices::SRandomDevice>());
qfs->ForceInsert("/dev", "zero", QuasiFS::Device::Create<Devices::ZeroDevice>());
qfs->ForceInsert("/dev", "null", QuasiFS::Device::Create<Devices::NopDevice>());
if (int fd_dev = qfs->Operation.Open("/dev/stdin", QUASI_O_RDONLY); fd_dev != 0)
LOG_CRITICAL(Kernel_Fs, "XDXDXD 0");
if (int fd_dev = qfs->Operation.Open("/dev/stdout", QUASI_O_WRONLY); fd_dev != 1)
LOG_CRITICAL(Kernel_Fs, "XDXDXD 1");
LOG_CRITICAL(Kernel_Fs, "XDXDXD 1 != {}",fd_dev);
if (int fd_dev = qfs->Operation.Open("/dev/stderr", QUASI_O_WRONLY); fd_dev != 2)
LOG_CRITICAL(Kernel_Fs, "XDXDXD 2");
LOG_CRITICAL(Kernel_Fs, "XDXDXD 2 != {}",fd_dev);
//
@ -147,6 +160,8 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder, const st
VideoCore::SetOutputDir(mount_captures_dir, id);
qfs->SyncHost();
// QuasiFS::printTree(qfs->GetRoot(), "/");
}
void Emulator::Run(std::filesystem::path file, const std::vector<std::string> args) {