diff --git a/src/common/fs_file.cpp b/src/common/fs_file.cpp index 810345b7d..cca75b79c 100644 --- a/src/common/fs_file.cpp +++ b/src/common/fs_file.cpp @@ -41,6 +41,11 @@ bool File::read(void* data, u64 size, u64* bytes_read) const { return isOpen() && *bytes_read == size; } +bool File::read(void* data, u64 size,u64 count, u64* bytes_read) const { + *bytes_read = std::fread(data, count, size, m_file); + return isOpen() && *bytes_read == size; +} + bool File::seek(s64 offset, SeekMode mode) { #ifdef _WIN64 if (!isOpen() || _fseeki64(m_file, offset, getSeekMode(mode)) != 0) { diff --git a/src/common/fs_file.h b/src/common/fs_file.h index bbefd08e5..4e0c093e5 100644 --- a/src/common/fs_file.h +++ b/src/common/fs_file.h @@ -31,6 +31,7 @@ class File { bool open(const std::string& path, OpenMode mode = OpenMode::Read); bool close(); bool read(void* data, u64 size, u64* bytes_read) const; + bool File::read(void* data, u64 size, u64 count, u64* bytes_read) const; bool write(std::span data); bool seek(s64 offset, SeekMode mode); u64 getFileSize(); diff --git a/src/core/hle/libraries/libc/libc_stdio.cpp b/src/core/hle/libraries/libc/libc_stdio.cpp index adbabb0eb..d50216276 100644 --- a/src/core/hle/libraries/libc/libc_stdio.cpp +++ b/src/core/hle/libraries/libc/libc_stdio.cpp @@ -28,7 +28,9 @@ int PS4_SYSV_ABI ps4_fprintf(FILE* file, VA_ARGS) { int PS4_SYSV_ABI ps4_vsnprintf(char* s, size_t n, const char* format, VaList* arg) { return vsnprintf_ctx(s, n, format, arg); } -int PS4_SYSV_ABI ps4_puts(const char* s) { return std::puts(s); } +int PS4_SYSV_ABI ps4_puts(const char* s) { + return std::puts(s); +} FILE* PS4_SYSV_ABI ps4_fopen(const char* filename, const char* mode) { LOG_INFO_IF(log_file_libc, "fopen filename={} , mode ={}\n", filename, mode); @@ -37,26 +39,66 @@ FILE* PS4_SYSV_ABI ps4_fopen(const char* filename, const char* mode) { u32 handle = h->createHandle(); auto* file = h->getFile(handle); + //file->m_mutex.lock(); file->m_guest_name = filename; file->m_host_name = mnt->getHostFile(file->m_guest_name); - FILE* f = std::fopen(file->m_host_name.c_str(), mode); - if (!f) { + if (!file->f.open(file->m_host_name.c_str(), Common::FS::OpenMode::Read)) { LOG_ERROR_IF(log_file_libc, "fopen can't open file={}\n", filename); } - return f; + FILE* descr = file->f.fileDescr(); + int handle1 = _fileno(descr); + file->isOpened = true; + //file->m_mutex.unlock(); + return descr; } -int PS4_SYSV_ABI ps4_fseek(FILE* stream, long int offset, int origin) { return std::fseek(stream, offset, origin); } +int PS4_SYSV_ABI ps4_fseek(FILE* stream, long int offset, int origin) { + auto* h = Common::Singleton::Instance(); + int handle = _fileno(stream); + auto* file = h->getFile(handle - 2); + file->m_mutex.lock(); + int seek = 0; + switch (origin) { + case 0: seek = file->f.seek(offset, Common::FS::SeekMode::Set); break; + case 1: seek = file->f.seek(offset, Common::FS::SeekMode::Cur); break; + case 2: seek = file->f.seek(offset, Common::FS::SeekMode::End); break; + } + file->m_mutex.unlock(); + return seek; +} -long PS4_SYSV_ABI ps4_ftell(FILE* stream) { return std::ftell(stream); } +long PS4_SYSV_ABI ps4_ftell(FILE* stream) { + auto* h = Common::Singleton::Instance(); + int handle = _fileno(stream); + auto* file = h->getFile(handle - 2); + //file->m_mutex.lock(); + long ftell = file->f.tell(); + //file->m_mutex.unlock(); + return ftell; +} -size_t PS4_SYSV_ABI ps4_fread(void* ptr, size_t size, size_t count, FILE* stream) { return std::fread(ptr, size, count, stream); } +size_t PS4_SYSV_ABI ps4_fread(void* ptr, size_t size, size_t count, FILE* stream) { + auto* h = Common::Singleton::Instance(); + int handle = _fileno(stream); + auto* file = h->getFile(handle - 2); + file->m_mutex.lock(); + u64 bytes_read = 0; + file->f.read(ptr, size,count, &bytes_read); + file->m_mutex.unlock(); + return bytes_read; +} int PS4_SYSV_ABI ps4_fclose(FILE* stream) { LOG_INFO_IF(log_file_libc, "fclose\n"); - if (stream != nullptr) { - std::fclose(stream); + auto* h = Common::Singleton::Instance(); + int handle = _fileno(stream); + auto* file = h->getFile(handle - 2); + //file->m_mutex.lock(); + if (file->isOpened) { + file->f.close(); } + h->deleteHandle(handle-2); + //file->m_mutex.unlock(); return 0; }