Copy bounded host reads into the destination in user mode so demand-committed pages can be handled by the process. Preserve short-read validation, zero-fill at EOF and HostWrite protection checks. Add synthetic read and Windows page-fault regressions. AI-assisted: yes.
Locking, trylocking, unlocking a destroyed mutex and signalling, broadcasting,
waiting on or destroying a destroyed condition variable threw a C++ exception
into the guest. FreeBSD 11.4 libthr returns EINVAL for all of them (thr_mutex.c
check_and_init_mutex and mutex_unlock_common compare against THR_MUTEX_DESTROYED,
thr_cond.c CHECK_AND_INIT_COND and _pthread_cond_destroy against
THR_COND_DESTROYED). The condition wait path already reported EINVAL for a
destroyed mutex.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
An adopted thread (the main thread, or a host thread that calls
scePthreadSelf) reported its whole Windows stack reservation, and so
did sceKernelIsStack on a host thread before adoption. A relinked
executable reserves 0x210000 bytes for its main thread and commits the
top 0x200000, so the lowest 64 KiB of the reported stack hold only
reserved pages and Windows' guard pages. mprotect fails there, so
HotSpot in Java 25 LAN / DNS (PPSA99869) could not create the main
thread's stack guard pages ("Attempt to allocate stack guard pages
failed").
When everything above the bottom allocation granule is committed
read-write, the host stack is now reported from there, as created
guest threads report only their committed stack. Other host stacks
keep the whole range. The committed-pages walk is shared with
StartNativeThread and throws when VirtualQuery fails.
fopen and freopen in an append mode gave the C runtime a descriptor with
_O_APPEND, which seeks to the end of the file and then writes. Streams on
separate descriptors overwrote each other's data. FreeBSD opens these
streams with O_APPEND, so every flush lands at the end of the file.
Open append streams with FILE_APPEND_DATA but without FILE_WRITE_DATA,
so Windows writes each flush at the end of the file. ftruncate and
flock reopen the file to get the access such a handle lacks.
A read event on a listening socket took its data from FIONREAD, which a listening socket refuses on Linux, so kevent and sceKernelAddReadEvent reported 0 connections while saying one was ready. FreeBSD 11.4 gives a listening socket filt_solisten, which reports so_qlen, the completed connections waiting for accept. Ready now checks SO_ACCEPTCONN and on Linux reads a TCP listener's accept backlog from TCP_INFO, where tcp_get_info puts it in tcpi_unacked; with no host call for the count (Windows, macOS, a listener that is not TCP) it reports 1, the lower bound the readiness already implies.
A mounted folder uses the junction reparse tag and would otherwise be returned as a relative Volume GUID path. Only a drive path is reported, through the absolute-link text helpers.
scePthreadJoin checked whether the thread was detached before whether it
was the calling thread. So a detached thread joining itself got EINVAL
instead of EDEADLK, and so did the main thread, which scePthreadSelf
adopts as detached. FreeBSD's join checks the calling thread right after
the null check and before it looks at the detach state. The self check
now comes first; the null, detached and already-joined answers are
unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sigprocmask and _sigprocmask threw std::invalid_argument for a how other
than SIG_BLOCK, SIG_UNBLOCK or SIG_SETMASK, which ends the title. FreeBSD
returns -1 with EINVAL and leaves the old mask uncopied, and ignores how
when set is null; pthread_sigmask here already returns EINVAL. The check
now comes first, before the previous mask is written.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>