From 9fce6f7c01f1328994e2ea91433cbe65f5444d84 Mon Sep 17 00:00:00 2001 From: Stephen Miller Date: Fri, 16 Aug 2024 17:20:21 -0500 Subject: [PATCH] Add SetPosixErrno function I used a switch statement for future proofing, as some codes differ between Windows, Mac, Linux, or Orbis. Right now I've only added the codes that should be possible to encounter. --- src/core/libraries/kernel/libkernel.cpp | 31 +++++ src/core/libraries/kernel/libkernel.h | 1 + .../libraries/kernel/thread_management.cpp | 118 ++---------------- 3 files changed, 39 insertions(+), 111 deletions(-) diff --git a/src/core/libraries/kernel/libkernel.cpp b/src/core/libraries/kernel/libkernel.cpp index 9657ba04..93afbc4f 100644 --- a/src/core/libraries/kernel/libkernel.cpp +++ b/src/core/libraries/kernel/libkernel.cpp @@ -125,6 +125,37 @@ int ErrnoToSceKernelError(int e) { return res > SCE_KERNEL_ERROR_ESTOP ? SCE_KERNEL_ERROR_UNKNOWN : res; } +void SetPosixErrno(int e) { + //Some error numbers are different between supported OSes or the PS4 + switch (e) { + case EPERM: + g_posix_errno = POSIX_EPERM; + break; + case EAGAIN: + g_posix_errno = POSIX_EAGAIN; + break; + case ENOMEM: + g_posix_errno = POSIX_ENOMEM; + break; + case EINVAL: + g_posix_errno = POSIX_EINVAL; + break; + case ENOSPC: + g_posix_errno = POSIX_ENOSPC; + break; + case ERANGE: + g_posix_errno = POSIX_ERANGE; + break; + case EDEADLK: + g_posix_errno = POSIX_EDEADLK; + break; + case ETIMEDOUT: + g_posix_errno = POSIX_ETIMEDOUT; + break; + default: + g_posix_errno = e; + } +} int PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, int prot, int flags, int fd, size_t offset, void** res) { LOG_INFO(Kernel_Vmm, "called addr = {}, len = {}, prot = {}, flags = {}, fd = {}, offset = {}", diff --git a/src/core/libraries/kernel/libkernel.h b/src/core/libraries/kernel/libkernel.h index 5b22dea4..5b7f1e72 100644 --- a/src/core/libraries/kernel/libkernel.h +++ b/src/core/libraries/kernel/libkernel.h @@ -14,6 +14,7 @@ namespace Libraries::Kernel { void ErrSceToPosix(int result); int ErrnoToSceKernelError(int e); +void SetPosixErrno(int e); struct OrbisTimesec { time_t t; diff --git a/src/core/libraries/kernel/thread_management.cpp b/src/core/libraries/kernel/thread_management.cpp index 19621424..68953269 100644 --- a/src/core/libraries/kernel/thread_management.cpp +++ b/src/core/libraries/kernel/thread_management.cpp @@ -1377,21 +1377,7 @@ int PS4_SYSV_ABI posix_pthread_detach(ScePthread thread) { int PS4_SYSV_ABI posix_sem_init(sem_t* sem, int pshared, unsigned int value) { int result = sem_init(sem, pshared, value); if (result == -1) { - switch (errno) { - case ENOMEM: - ErrSceToPosix(ORBIS_KERNEL_ERROR_ENOMEM); - break; - case EPERM: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EPERM); - break; - case ENOSPC: - ErrSceToPosix(ORBIS_KERNEL_ERROR_ENOSPC); - break; - case EINVAL: - default: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EINVAL); - break; - } + SetPosixErrno(errno); } return result; } @@ -1399,21 +1385,7 @@ int PS4_SYSV_ABI posix_sem_init(sem_t* sem, int pshared, unsigned int value) { int PS4_SYSV_ABI posix_sem_wait(sem_t* sem) { int result = sem_wait(sem); if (result == -1) { - switch (errno) { - case ENOMEM: - ErrSceToPosix(ORBIS_KERNEL_ERROR_ENOMEM); - break; - case EPERM: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EPERM); - break; - case ETIMEDOUT: - ErrSceToPosix(ORBIS_KERNEL_ERROR_ETIMEDOUT); - break; - case EINVAL: - default: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EINVAL); - break; - } + SetPosixErrno(errno); } return result; } @@ -1421,21 +1393,7 @@ int PS4_SYSV_ABI posix_sem_wait(sem_t* sem) { int PS4_SYSV_ABI posix_sem_trywait(sem_t* sem) { int result = sem_trywait(sem); if (result == -1) { - switch (errno) { - case ENOMEM: - ErrSceToPosix(ORBIS_KERNEL_ERROR_ENOMEM); - break; - case EPERM: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EPERM); - break; - case EAGAIN: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EAGAIN); - break; - case EINVAL: - default: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EINVAL); - break; - } + SetPosixErrno(errno); } return result; } @@ -1473,21 +1431,7 @@ int sem_timedwait(sem_t* sem, const struct timespec* abstime) { int PS4_SYSV_ABI posix_sem_timedwait(sem_t* sem, const timespec* t) { int result = sem_timedwait(sem, t); if (result == -1) { - switch (errno) { - case ENOMEM: - ErrSceToPosix(ORBIS_KERNEL_ERROR_ENOMEM); - break; - case EPERM: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EPERM); - break; - case ETIMEDOUT: - ErrSceToPosix(ORBIS_KERNEL_ERROR_ETIMEDOUT); - break; - case EINVAL: - default: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EINVAL); - break; - } + SetPosixErrno(errno); } return result; } @@ -1495,21 +1439,7 @@ int PS4_SYSV_ABI posix_sem_timedwait(sem_t* sem, const timespec* t) { int PS4_SYSV_ABI posix_sem_post(sem_t* sem) { int result = sem_post(sem); if (result == -1) { - switch (errno) { - case ENOMEM: - ErrSceToPosix(ORBIS_KERNEL_ERROR_ENOMEM); - break; - case EPERM: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EPERM); - break; - case ERANGE: - ErrSceToPosix(ORBIS_KERNEL_ERROR_ERANGE); - break; - case EINVAL: - default: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EINVAL); - break; - } + SetPosixErrno(errno); } return result; } @@ -1517,24 +1447,7 @@ int PS4_SYSV_ABI posix_sem_post(sem_t* sem) { int PS4_SYSV_ABI posix_sem_destroy(sem_t* sem) { int result = sem_destroy(sem); if (result == -1) { - switch (errno) { - case ENOMEM: - ErrSceToPosix(ORBIS_KERNEL_ERROR_ENOMEM); - break; - case EPERM: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EPERM); - break; - case ETIMEDOUT: - ErrSceToPosix(ORBIS_KERNEL_ERROR_ETIMEDOUT); - break; - case EDEADLK: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EDEADLK); - break; - case EINVAL: - default: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EINVAL); - break; - } + SetPosixErrno(errno); } return result; } @@ -1542,24 +1455,7 @@ int PS4_SYSV_ABI posix_sem_destroy(sem_t* sem) { int PS4_SYSV_ABI posix_sem_getvalue(sem_t* sem, int* sval) { int result = sem_getvalue(sem, sval); if (result == -1) { - switch (errno) { - case ENOMEM: - ErrSceToPosix(ORBIS_KERNEL_ERROR_ENOMEM); - break; - case EPERM: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EPERM); - break; - case ETIMEDOUT: - ErrSceToPosix(ORBIS_KERNEL_ERROR_ETIMEDOUT); - break; - case EDEADLK: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EDEADLK); - break; - case EINVAL: - default: - ErrSceToPosix(ORBIS_KERNEL_ERROR_EINVAL); - break; - } + SetPosixErrno(errno); } return result; }