Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions core/libs/prx/libkernel/System/src/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ extern "C" int* APS5_VABI __error_nid_postfix();
namespace {

constexpr int sceInvalidArgument = static_cast<int>(0x80020016u);
constexpr int errnoNoProcess = 3;
constexpr int errnoNoChild = 10;
constexpr int errnoInvalidArgument = 22;
constexpr unsigned freebsdWaitOptions = 0x8000003Fu;
Expand Down Expand Up @@ -201,9 +202,12 @@ int APS5_VABI getpid_nid_postfix(void) {
}

int APS5_VABI getsid_nid_postfix(int pid) {
(void)pid;
NotImplemented_nid_no_patch("getsid: process sessions");
return -1;
const int self = getpid_nid_postfix();
if (pid != 0 && pid != self) {
*__error_nid_postfix() = errnoNoProcess;
return -1;
}
return self;
}

int APS5_VABI getppid_nid_postfix(void) {
Expand Down
25 changes: 13 additions & 12 deletions core/libs/tests/GuestIoctlGetsid.cpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
#include "prx/libc/include/general/VabiMacros.hpp"
#include <cstdlib>
#include <stdexcept>
#include <string>
extern "C" {
int APS5_VABI getpid_nid_postfix(void);
int APS5_VABI getsid_nid_postfix(int);
int* APS5_VABI __error_nid_postfix();
}
static void Require(bool value) { if (!value) std::abort(); }
template <typename Call>
static bool ReportsNotImplemented(Call call, const std::string& message) {
try {
call();
} catch (const std::runtime_error& error) {
return error.what() == message;
}
return false;
static bool ReportsNoProcess(int pid) {
*__error_nid_postfix() = 0;
return getsid_nid_postfix(pid) == -1 && *__error_nid_postfix() == 3;
}
int main() {
Require(ReportsNotImplemented([] { getsid_nid_postfix(0); }, "getsid: process sessions not implemented"));
Require(ReportsNotImplemented([] { getsid_nid_postfix(1); }, "getsid: process sessions not implemented"));
const int self = getpid_nid_postfix();
*__error_nid_postfix() = 0;
Require(getsid_nid_postfix(0) == self);
Require(getsid_nid_postfix(self) == self);
Require(*__error_nid_postfix() == 0);
Require(ReportsNoProcess(self == 1 ? 2 : 1));
Require(ReportsNoProcess(-self));
Require(ReportsNoProcess(-1));
}
2 changes: 1 addition & 1 deletion docs/dev/TechnicalDebt.md
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@ Throughout the project, every function at every stage either **does exactly what
- [daemon](../../core/libs/prx/libc/src/Process.cpp) (libc) throws: forking into the background is not supported. PPSA85300 imports it and fails to load without it. VLC 3.0 calls it only when its `daemon` option is set ([libvlc.c](https://github.com/videolan/vlc/blob/6de05adcbaf2e8b85fe86aad4169393098628119/src/libvlc.c#L190-L197)), and the title starts libVLC with `--ignore-config` and without `--daemon` ([player.cc](https://github.com/ZiZc3/VLC/blob/f3253020a64368153233ede29183014c0b6c8979/src/player.cc#L960-L981))
- [sigtimedwait](../../core/libs/prx/libkernel/System/src/Signals.cpp) (libkernel) throws: guest signals are delivered when raised and never left pending, so there is nothing to wait for or take. PPSA85300 imports it and fails to load without it. Its only call site is VLC's `vlc_writev` ([filesystem.c](https://github.com/videolan/vlc/blob/6de05adcbaf2e8b85fe86aad4169393098628119/src/posix/filesystem.c#L243-L278)), which polls with a zero timeout to drain a `SIGPIPE` only after `writev` fails with `EPIPE`
- [pause, sigwait, sigwaitinfo](../../core/libs/prx/libkernel/System/src/Signals.cpp) (libkernel) throw, as `sigtimedwait` does: guest signals are never left pending, so `sigwait` and `sigwaitinfo` have nothing to take, and `pause` would wait for a handler that `raise`, `kill` and `pthread_kill` only run on the calling thread. PPSA68091, PPSA99169, PPSA99420 and PPSA97358 import them and fail to load without them. PPSA68091 calls `pause` at one site (0x8F7266), in a loop that waits while a global holds another thread's `errno` address. PPSA99169 only stores the address of `pause` in a table of symbol addresses (0x30DB1). PPSA99420 calls `pause` at 0x3BD80F6 and 0x3C9E220, `sigwait` at 0x3C9E4C7 and `sigwaitinfo` at 0x3C9E588. PPSA97358 calls `sigwait` from QEMU's `sigwait_compat` thread ([compatfd.c](https://github.com/ZiZc3/XPSemu/blob/8eec07b4e31f66dce8e0b05c1ca1281af303e933/util/compatfd.c#L28-L53)), which `qemu_signal_init` ([main-loop.c](https://github.com/ZiZc3/XPSemu/blob/8eec07b4e31f66dce8e0b05c1ca1281af303e933/util/main-loop.c#L110-L147)) starts for `SIGIO`, `SIGALRM` and `SIGBUS` when the main loop is created, so it reaches the throw at start-up, and from the vCPU thread of the dummy accelerator ([dummy-cpus.c](https://github.com/ZiZc3/XPSemu/blob/8eec07b4e31f66dce8e0b05c1ca1281af303e933/accel/dummy-cpus.c#L48-L56))
- [getsid](../../core/libs/prx/libkernel/System/src/Process.cpp) (libkernel) throws: process sessions are not modelled. PPSA74126 imports it and fails to load without it; the title made no call to it in a 60 s run
- [getsid](../../core/libs/prx/libkernel/System/src/Process.cpp) (libkernel) follows FreeBSD's `kern_getsid` ([kern_prot.c](https://github.com/freebsd/freebsd-src/blob/main/sys/kern/kern_prot.c)) for the only guest process: 0 and its own pid return its session id, any other pid reports `ESRCH`. The session id is its own pid: the guest is taken to lead its own session, as it is taken to lead its own process group (see `kill` and `setsid`). The session a title belongs to on a console is not measured. PPSA74126 imports it; the title made no call to it in a 60 s run
- [sigaction](../../core/libs/prx/libkernel/System/src/Signals.cpp) (libkernel) records the handler, flags and mask of every signal from 1 to 128 and reports them back, following FreeBSD's `sigaction` (`EINVAL` for other signals, and for a handler on `SIGKILL` or `SIGSTOP`); `signal` records its handler with `SA_RESTART`, as FreeBSD's libc does. Only handlers without `SA_SIGINFO` on the signals `signal` already delivers (`SIGINT`, `SIGILL`, `SIGABRT`, `SIGFPE`, `SIGSEGV`, `SIGTERM`) run, the same way `signal` handlers do; their mask and flags are not applied. `SA_SIGINFO` handlers are recorded but never called, since that needs FreeBSD's `siginfo_t` and `ucontext_t`, and neither are the handlers of other signals (`SIGBUS`, `SIGHUP`, ...), whether they are set by `sigaction` or by `signal`, which records them too (every number from 1 to 128, with `SA_RESTART` and an empty mask replacing what `sigaction` stored; `SIGKILL` and `SIGSTOP` accept only the default handler in both calls, as in FreeBSD's `kern_sigaction`). `raise` of an `SA_SIGINFO` handler on a signal `signal` delivers throws instead of terminating, and `raise` and `kill` of the other signals still fail with `EINVAL`, recorded handler or not
- [kill](../../core/libs/prx/libkernel/System/src/Signals.cpp) (libkernel) follows FreeBSD's `kern_kill` and `killpg1` for the only guest process: `EINVAL` for signals outside 0 to 128, signal 0 only checks that the target exists, and its own pid, 0 and minus its own pid (the guest is taken to lead its own process group) signal it through `raise`, so they share `raise`'s limits above. Any other pid, and -1, which skips the caller, report `ESRCH`, so `EPERM` is never reported
- [sceKernelFcntl](../../core/libs/prx/libkernel/File/src/Open.cpp) (libkernel) handles socket descriptors through the POSIX `fcntl` export (`F_GETFL`, `F_SETFL` with `O_NONBLOCK`) and returns its guest errno as `SCE_KERNEL_ERROR_*`, the form the other `sceKernel` file exports use; the command semantics follow FreeBSD's [fcntl](https://github.com/freebsd/freebsd-src/blob/stable/11/sys/kern/kern_descrip.c), and a closed descriptor returns `SCE_KERNEL_ERROR_EBADF`. File descriptors throw: their open flags are not tracked, and `F_DUPFD`, `F_GETFD` and `F_SETFD` are unsupported on all descriptors. The return values and error codes are unverified on a console
Expand Down
Loading