link took the source's std::filesystem::status first, and MinGW-w64's
libstdc++ reports a Windows symbolic link loop as not found (ENOENT), so
it returned ENOENT before FollowLinkPath, which maps the loop's
ERROR_CANT_RESOLVE_FILENAME to ELOOP, was reached. guest_kernel_sys's
loop case failed at that check wherever symbolic links can be created
(Windows 11 22H2: "check failed at line 835 (guest errno 2)").
When the status reports the source missing, ask FollowLinkPath first:
a loop now returns ELOOP and a dangling link still ENOENT; a missing
path is unchanged.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Read the clock of a libkernel condition attribute, returning
SCE_KERNEL_ERROR_EINVAL for a null or destroyed attribute as
scePthreadCondattrSetclock does, after FreeBSD 11.4 libthr's
_pthread_condattr_getclock. A null clock pointer throws.
The EINVAL for a descriptor without a vnode now applies only to a pipe or socket. A character device is a vnode on FreeBSD, so getvnode succeeds and change_dir fails with ENOTDIR; File::IsCharacterDevice keeps that answer for the host character devices (a tty, NUL or /dev/null) and the guest random device. guest_kernel_sys pins it with /dev/random.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
FreeBSD 11.4's sys_fchdir resolves the descriptor with getvnode, which fails with EINVAL for a descriptor that has no vnode; only a vnode that is not a directory gives ENOTDIR from change_dir. fchdir returned ENOTDIR for a pipe or socket. A descriptor that is neither a vnode nor a random device now gets EINVAL; the debt entry records the order of the three errors.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Forward scePthreadBarrier*, scePthreadBarrierattr*, scePthreadGetcpuclockid,
scePthreadGetconcurrency and sceKernelMsync to libkernel's POSIX
implementations and return POSIX errors as SCE kernel errors.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The PS5 3.20 export lists have ktimer_* in libkernel as well as
libkernel_sys, and on Windows a libkernel import never reaches
libkernel_sys. The implementation moves unchanged to
libkernel/Time/Ktimer.cpp.
Resolves the conflict with #8522 in link_nid_postfix: keep its ENOTDIR
return for a destination below a regular file and the Windows
symbolic-link follow after it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
link_nid_postfix decided whether to follow the source with
std::filesystem::is_symlink, which MinGW-w64's libstdc++ never reports for
a Windows symbolic link, so on Windows link made a hard link to the link
itself. Follow a reparse-point source to its final path with
GetFinalPathNameByHandleW instead, and run the link-through-a-link case of
guest_kernel_sys on Windows too.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Write the low 32 bits of the SDK version field at offset 0x10 of the
title's process parameters and return EINVAL (0x80020016) for a null
output, following shadPS4.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01WYjMwvLdPR8iX8EP8tQYWa
Both were missing from libkernel.prx, so a title importing either
(dYv-+If2GPk, RRnSj8h8VR4) failed to load. They take a relative timeout
in microseconds and are scePthreadRwlockTimedrdlock and
scePthreadRwlockTimedwrlock with POSIX error numbers; a zero lock is
initialized as by pthread_rwlock_rdlock. The signature comes from
shadPS4, which registers one function for each NID and its
scePthreadRwlockTimed* twin; FreeBSD 11.4 has no such calls. The throwing
libkernel_sys copies are removed, as an export may live in one library
only. Recorded in the libkernel debt file.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
lchmod forwards to fchmodat with AT_FDCWD and AT_SYMLINK_NOFOLLOW, as
FreeBSD 11.4's sys_lchmod does. On Linux and Windows, which cannot change
the mode of a symbolic link itself, a symbolic link throws instead of
succeeding without a change.
fstat was a NotImplemented stub in libkernel_sys. It now calls libkernel's
_fstat, as fstatfs already calls _fstatfs, so it reports the same status,
EFAULT for a null buffer and EBADF for a descriptor that is not open.
FreeBSD lookup() refuses "." and ".." as the last component of a DELETE
lookup with EINVAL (sys/kern/vfs_lookup.c:750-754 and 823-826), before the
unlink and rmdir checks run. unlink and sceKernelUnlink answered EPERM,
rmdir and sceKernelRmdir answered ENOTEMPTY for "..", and unlinkat without
AT_REMOVEDIR answered EPERM. Reuse the RenameDot check added for rename, so a
missing or non-directory parent still reports ENOENT or ENOTDIR first.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>