mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-04-29 23:41:19 -06:00
internal__Foprep (and various other functions called in it)
This commit is contained in:
parent
ebd62b525d
commit
0a2d864884
@ -11,9 +11,9 @@
|
||||
#include "core/libraries/kernel/file_system.h"
|
||||
#include "core/libraries/kernel/kernel.h"
|
||||
#include "core/libraries/kernel/posix_error.h"
|
||||
#include "core/libraries/kernel/threads.h"
|
||||
#include "core/libraries/libc_internal/libc_internal_io.h"
|
||||
#include "core/libraries/libc_internal/libc_internal_threads.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "libc_internal_io.h"
|
||||
#include "printf.h"
|
||||
|
||||
namespace Libraries::LibcInternal {
|
||||
@ -55,18 +55,128 @@ OrbisFILE* PS4_SYSV_ABI internal__Fofind() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PS4_SYSV_ABI internal__Lockfilelock(OrbisFILE* file) {
|
||||
if (file != nullptr && file->_Mutex != nullptr) {
|
||||
internal__Mtxlock(&file->_Mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void PS4_SYSV_ABI internal__Unlockfilelock(OrbisFILE* file) {
|
||||
if (file != nullptr && file->_Mutex != nullptr) {
|
||||
internal__Mtxunlock(&file->_Mutex);
|
||||
}
|
||||
}
|
||||
|
||||
OrbisFILE* PS4_SYSV_ABI internal__Foprep(const char* path, const char* mode, OrbisFILE* file,
|
||||
s32 fd, s32 flag1, s32 flag2) {
|
||||
s32 fd, s32 s_mode, s32 flag) {
|
||||
if (file == nullptr) {
|
||||
*Kernel::__Error() = POSIX_ENOMEM;
|
||||
}
|
||||
|
||||
// Preserve mode and index
|
||||
Libraries::Kernel::PthreadMutexT file_mtx = file->_Mutex;
|
||||
u8 file_index = file->_Idx;
|
||||
u16 file_mode = file->_Mode & 0x80;
|
||||
|
||||
// Real library does a memcpy using a static global FILE object.
|
||||
// This stored file is just zeros, with the only exception being a handle of -1.
|
||||
memset(file, 0, sizeof(OrbisFILE));
|
||||
file->_Handle = -1;
|
||||
|
||||
// TODO: The rest of this.
|
||||
// Not sure what this magic is for, but I'll replicate it.
|
||||
u8* ptr = &file->_Cbuf;
|
||||
// Note: this field is supposed to be a pthread mutex.
|
||||
// Since we don't export pthread HLEs for other functions, I'll avoid handling this for now.
|
||||
file->_Mutex = nullptr;
|
||||
file->_Idx = file_index;
|
||||
file->_Buf = ptr;
|
||||
file->_Bend = &file->unk2;
|
||||
file->_Next = ptr;
|
||||
file->_Rend = ptr;
|
||||
file->_WRend = ptr;
|
||||
file->_Wend = ptr;
|
||||
file->_WWend = ptr;
|
||||
file->_Rback = ptr;
|
||||
file->_WRback = &file->unk1;
|
||||
|
||||
// Parse inputted mode string
|
||||
char* mode_str = *mode;
|
||||
u16 calc_mode = 0;
|
||||
u16 access_mode = 0;
|
||||
if (mode_str[0] == 'r') {
|
||||
calc_mode = 1 | file_mode;
|
||||
} else if (mode_str[0] == 'w') {
|
||||
calc_mode = 0x1a | file_mode;
|
||||
} else if (mode_str[0] == 'a') {
|
||||
calc_mode = 0x16 | file_mode;
|
||||
} else {
|
||||
// Closes the file and returns EINVAL.
|
||||
file->_Mode = file_mode;
|
||||
if (flag == 0) {
|
||||
internal__Mtxinit(&file_mtx, nullptr);
|
||||
} else {
|
||||
file->_Mutex = file_mtx;
|
||||
internal__Unlockfilelock(file);
|
||||
}
|
||||
internal_fclose(file);
|
||||
*Kernel::__Error() = POSIX_EINVAL;
|
||||
return nullptr;
|
||||
}
|
||||
file->_Mode = calc_mode;
|
||||
|
||||
do {
|
||||
// This is all basically straight from decomp, need to cleanup at some point.
|
||||
if (mode_str[1] == '+') {
|
||||
file_mode = 3;
|
||||
if ((~calc_mode & 3) == 0) {
|
||||
break;
|
||||
}
|
||||
} else if (mode_str[1] != 'b') {
|
||||
file_mode = 0x20;
|
||||
if ((calc_mode & 0x20) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
mode_str++;
|
||||
calc_mode = file_mode | calc_mode;
|
||||
file->_Mode = calc_mode;
|
||||
} while (true);
|
||||
|
||||
if (path == nullptr && fd >= 0) {
|
||||
// I guess this is for some internal behavior?
|
||||
file->_Handle = fd;
|
||||
} else {
|
||||
fd = internal__Fopen(path, calc_mode, s_mode == 0x55);
|
||||
file->_Handle = fd;
|
||||
}
|
||||
|
||||
// Error case
|
||||
if (fd < 0) {
|
||||
// Closes the file, but ensures errno is unchanged.
|
||||
if (flag == 0) {
|
||||
internal__Mtxinit(&file_mtx, nullptr);
|
||||
} else {
|
||||
file->_Mutex = file_mtx;
|
||||
internal__Unlockfilelock(file);
|
||||
}
|
||||
s32 old_errno = *Kernel::__Error();
|
||||
internal_fclose(file);
|
||||
*Kernel::__Error() = old_errno;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (flag == 0) {
|
||||
char mtx_name[0x20];
|
||||
std::snprintf(mtx_name, 0x20, "FileFD:0x%08X", fd);
|
||||
internal__Mtxinit(&file_mtx, mtx_name);
|
||||
} else {
|
||||
file->_Mutex = file_mtx;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI internal__Fopen(const char* path, u16 mode, bool flag) {}
|
||||
|
||||
OrbisFILE* PS4_SYSV_ABI internal_fopen(const char* path, const char* mode) {
|
||||
std::scoped_lock lk{g_stream_mtx};
|
||||
|
||||
@ -89,6 +199,10 @@ void RegisterlibSceLibcInternalIo(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("eLdDw6l0-bU", "libSceLibcInternal", 1, "libSceLibcInternal", internal_snprintf);
|
||||
LIB_FUNCTION("xGT4Mc55ViQ", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Fofind);
|
||||
LIB_FUNCTION("dREVnZkAKRE", "libSceLibcInternal", 1, "libSceLibcInternal", internal__Foprep);
|
||||
LIB_FUNCTION("vZkmJmvqueY", "libSceLibcInternal", 1, "libSceLibcInternal",
|
||||
internal__Lockfilelock);
|
||||
LIB_FUNCTION("0x7rx8TKy2Y", "libSceLibcInternal", 1, "libSceLibcInternal",
|
||||
internal__Unlockfilelock);
|
||||
}
|
||||
|
||||
void ForceRegisterlibSceLibcInternalIo(Core::Loader::SymbolsResolver* sym) {
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
|
||||
#include <mutex>
|
||||
#include "common/types.h"
|
||||
#include "core/libraries/kernel/threads.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
class SymbolsResolver;
|
||||
@ -48,7 +49,7 @@ struct OrbisFILE {
|
||||
u8* _Tmpnam;
|
||||
u8 _Back[6], _Cbuf;
|
||||
u8 unk2;
|
||||
void* _Mutex;
|
||||
Libraries::Kernel::PthreadMutexT _Mutex;
|
||||
u8* _p;
|
||||
s32 _r;
|
||||
s32 _w;
|
||||
@ -78,6 +79,8 @@ struct OrbisFILE {
|
||||
|
||||
s32 PS4_SYSV_ABI internal_snprintf(char* s, u64 n, VA_ARGS);
|
||||
OrbisFILE* PS4_SYSV_ABI internal__Fofind();
|
||||
void PS4_SYSV_ABI internal__Lockfilelock(OrbisFILE* file);
|
||||
void PS4_SYSV_ABI internal__Unlockfilelock(OrbisFILE* file);
|
||||
OrbisFILE* PS4_SYSV_ABI internal__Foprep(const char* path, const char* mode, OrbisFILE* file,
|
||||
s32 fd, s32 flag1, s32 flag2);
|
||||
OrbisFILE* PS4_SYSV_ABI internal_fopen(const char* path, const char* mode);
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
|
||||
#include <mutex>
|
||||
#include "common/types.h"
|
||||
#include "core/libraries/kernel/threads.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
class SymbolsResolver;
|
||||
@ -12,5 +13,10 @@ class SymbolsResolver;
|
||||
|
||||
namespace Libraries::LibcInternal {
|
||||
|
||||
s32 PS4_SYSV_ABI internal__Mtxinit(Libraries::Kernel::PthreadMutexT* mtx, const char* name);
|
||||
s32 PS4_SYSV_ABI internal__Mtxlock(Libraries::Kernel::PthreadMutexT* mtx);
|
||||
s32 PS4_SYSV_ABI internal__Mtxunlock(Libraries::Kernel::PthreadMutexT* mtx);
|
||||
s32 PS4_SYSV_ABI internal__Mtxdst(Libraries::Kernel::PthreadMutexT* mtx);
|
||||
|
||||
void RegisterlibSceLibcInternalThreads(Core::Loader::SymbolsResolver* sym);
|
||||
}
|
||||
} // namespace Libraries::LibcInternal
|
||||
Loading…
Reference in New Issue
Block a user