diff --git a/CMakeLists.txt b/CMakeLists.txt index 6959ac169..acdebd8fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -777,6 +777,8 @@ set(CORE src/core/aerolib/stubs.cpp 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/null_device.cpp + src/core/file_sys/devices/null_device.h src/core/file_sys/devices/random_device.cpp src/core/file_sys/devices/random_device.h src/core/file_sys/devices/srandom_device.cpp diff --git a/src/core/file_sys/devices/null_device.cpp b/src/core/file_sys/devices/null_device.cpp new file mode 100644 index 000000000..4ecf9f372 --- /dev/null +++ b/src/core/file_sys/devices/null_device.cpp @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include + +#include "null_device.h" + +namespace Core::Devices { + +NullDevice::NullDevice() = default; +NullDevice::~NullDevice() = default; + +s64 NullDevice::read(void* buf, u64 count) { + return 0; +} + +s64 NullDevice::write(const void* buf, u64 count) { + return count; +} + +s64 NullDevice::pread(void* buf, size_t count, u64 offset) { + return 0; +} + +s64 NullDevice::pwrite(const void* buf, size_t count, u64 offset) { + return count; +} + +} // namespace Core::Devices \ No newline at end of file diff --git a/src/core/file_sys/devices/null_device.h b/src/core/file_sys/devices/null_device.h new file mode 100644 index 000000000..ed015f64f --- /dev/null +++ b/src/core/file_sys/devices/null_device.h @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "core/file_sys/quasifs/quasifs_inode_device.h" + +namespace Core::Devices { + +class NullDevice final : public QuasiFS::Device { + +public: + NullDevice(); + ~NullDevice(); + + 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; + + // 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 \ No newline at end of file diff --git a/src/core/file_sys/devices/random_device.cpp b/src/core/file_sys/devices/random_device.cpp index 6d72a45c9..fdb3bcfc2 100644 --- a/src/core/file_sys/devices/random_device.cpp +++ b/src/core/file_sys/devices/random_device.cpp @@ -22,4 +22,20 @@ s64 RandomDevice::read(void* buf, u64 count) { return count; } +s64 RandomDevice::write(const void* buf, u64 count) { + return count; +} + +s64 RandomDevice::pread(void* buf, u64 count, u64 offset) { + auto rbuf = static_cast(buf); + for (size_t i = 0; i < count; i++) { + rbuf[i] = std::rand() & 0xFF; + } + return count; +} + +s64 RandomDevice::pwrite(const void* buf, u64 count, u64 offset) { + return count; +} + } // namespace Core::Devices \ No newline at end of file diff --git a/src/core/file_sys/devices/random_device.h b/src/core/file_sys/devices/random_device.h index 690cffc75..d0284ccdf 100644 --- a/src/core/file_sys/devices/random_device.h +++ b/src/core/file_sys/devices/random_device.h @@ -15,12 +15,12 @@ public: ~RandomDevice(); 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 ; // 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(); } diff --git a/src/core/file_sys/quasifs/quasifs_inode_device.h b/src/core/file_sys/quasifs/quasifs_inode_device.h index 9d0f5cdfb..68729702c 100644 --- a/src/core/file_sys/quasifs/quasifs_inode_device.h +++ b/src/core/file_sys/quasifs/quasifs_inode_device.h @@ -11,7 +11,7 @@ #define DEVICE_STUB() \ { \ LOG_ERROR(Kernel_Fs, "(STUBBED) called"); \ - return 0; \ + return -QUASI_ENOSYS; \ } namespace QuasiFS { diff --git a/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp b/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp index ddbb042a0..bcddd7447 100644 --- a/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp +++ b/src/core/file_sys/quasifs/src/quasifs_vdriver.cpp @@ -31,7 +31,7 @@ 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(res.parent); - bool request_read = (flags & (QUASI_O_WRONLY | QUASI_O_RDWR)) == 0; + bool request_read = !(flags & QUASI_O_WRONLY) || (flags & QUASI_O_RDWR); bool request_write = (flags & (QUASI_O_WRONLY | QUASI_O_RDWR)) != 0; bool request_append = flags & QUASI_O_APPEND; @@ -556,8 +556,7 @@ s64 QFS::OperationImpl::Read(const s32 fd, void* buf, u64 count) { if (host_used && (hio_status != vio_status)) LogError("Host returned {}, but virtual driver returned {}", hio_status, vio_status); - return hio_status; - // return vio_status; + return vio_status; } s64 QFS::OperationImpl::PRead(const s32 fd, void* buf, u64 count, u64 offset) { diff --git a/src/emulator.cpp b/src/emulator.cpp index 4ac05c796..0e6e65b2a 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -55,6 +55,7 @@ #include "core/file_sys/devices/random_device.h" #include "core/file_sys/devices/srandom_device.h" #include "core/file_sys/devices/zero_device.h" +#include "core/file_sys/devices/null_device.h" Frontend::WindowSDL* g_window = nullptr; @@ -104,7 +105,7 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder, const st qfs->Operation.MKDir("/app0", 0555); qfs->Operation.MKDir("/data", 0777); - qfs->Operation.MKDir("/dev", 0755); + qfs->Operation.MKDir("/dev", 0555); qfs->Operation.MKDir("/download0", 0777); // not sure about perms here qfs->Operation.MKDir("/hostapp", 0777); qfs->Operation.MKDir("/temp", 0777); @@ -125,10 +126,11 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder, const st // qfs->Operation.MKDir("/dev/fd"); - qfs->ForceInsert("/dev/fd", "0", QuasiFS::Device::Create()); + qfs->ForceInsert("/dev/fd", "0", QuasiFS::Device::Create()); qfs->ForceInsert("/dev/fd", "1", QuasiFS::Device::Create("stdout", false)); // qfs->ForceInsert("/dev/fd", "1", std::make_shared("stdout", false)); qfs->ForceInsert("/dev/fd", "2", QuasiFS::Device::Create("stderr", true)); + // stdin is unavailable from within the app??? qfs->Operation.LinkSymbolic("/dev/fd/0", "/dev/stdin"); qfs->Operation.LinkSymbolic("/dev/fd/1", "/dev/stdout"); qfs->Operation.LinkSymbolic("/dev/fd/2", "/dev/stderr"); @@ -142,7 +144,13 @@ void Emulator::LoadFilesystem(const std::filesystem::path& game_folder, const st qfs->ForceInsert("/dev", "urandom", QuasiFS::Device::Create()); qfs->ForceInsert("/dev", "srandom", QuasiFS::Device::Create()); qfs->ForceInsert("/dev", "zero", QuasiFS::Device::Create()); - qfs->ForceInsert("/dev", "null", QuasiFS::Device::Create()); + qfs->ForceInsert("/dev", "null", QuasiFS::Device::Create()); + + qfs->Operation.Chmod("/dev/deci_stderr",0666); + qfs->Operation.Chmod("/dev/deci_stdout",0666); + qfs->Operation.Chmod("/dev/random",0666); + qfs->Operation.Chmod("/dev/urandom",0666); + qfs->Operation.Chmod("/dev/srandom",0666); if (int fd_dev = qfs->Operation.Open("/dev/stdin", QUASI_O_RDONLY); fd_dev != 0) LOG_CRITICAL(Kernel_Fs, "XDXDXD 0");