Commit Graph
146 Commits
Author SHA1 Message Date
xXPBSXxandClaude Sonnet 5.5 308848e1a6 fix(libc): resolve the rename source before the destination argument
FreeBSD 11.4 kern_renameat looks up the source first (namei on fromnd),
so a missing or dot source fails with ENOENT or EINVAL before the new
name is touched. The guest call rejected a NULL, empty or dot destination
first, so rename(missing, NULL) returned EFAULT and rename(missing, ".")
returned EINVAL where FreeBSD returns ENOENT.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 12:51:02 +02:00
Adrià a0e0985288 Merge pull request #7551 from mazen320/fix/open-nofollow-junction
fix(libkernel): stop O_NOFOLLOW from opening a Windows directory junction
2026-10-20 12:20:01 +02:00
SebastianandClaude Opus 5.5 cfdaf2dbb8 feat(libkernel): implement fchflags
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QnkpF2oEMofseVz9Z7WEAC
2026-10-20 07:28:54 +00:00
xXPBSXxandClaude Sonnet 5.5 972fb84988 fix(libc): fail chdir, remove, opendir and fopen through a regular file with ENOTDIR on Windows
A path whose directory part is a regular file, such as file/child, failed
with ENOENT in chdir, remove, opendir, fopen and freopen on Windows, where
FreeBSD 11.4 fails it with ENOTDIR (vfs_cache_lookup, sys/kern/vfs_cache.c).
The not-found error of these calls now asks whether the nearest existing
ancestor is not a directory, as open, stat, lstat, access and unlink do.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 07:54:18 +02:00
xXPBSXxandClaude Sonnet 5.5 7f32f42627 fix(libkernel): fail chmod, truncate, utimes and rename through a regular file with ENOTDIR on Windows
A path whose directory part is a regular file, such as file/child, failed
with ENOENT in chmod, truncate, utimes and rename on Windows, where FreeBSD
11.4 fails it with ENOTDIR (vfs_cache_lookup, sys/kern/vfs_cache.c). The
not-found error of these calls now asks whether the nearest existing
ancestor is not a directory, as open, stat, lstat, access and unlink do.
For rename the source ancestor is checked first and the destination ancestor
only while the source exists. A test line that expected ENOENT for truncate
of a path below a regular file now expects ENOTDIR.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 06:01:12 +02:00
xXPBSXxandClaude Sonnet 5.5 cb6cd768ef fix(libkernel): fail open, stat, lstat, access and unlink through a regular file with ENOTDIR on Windows
A path whose directory part is a regular file, such as file/child, failed
with ENOENT in open, stat, lstat, access and unlink on Windows, where
FreeBSD 11.4 lookup fails it with ENOTDIR (vfs_cache_lookup, sys/kern/vfs_cache.c).
mkdir and rmdir already did. A not-found error of these calls now asks whether the
nearest existing ancestor is not a directory and reports ENOTDIR then.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 06:00:15 +02:00
Dean 525e299fc0 Merge pull request #8184 from xXPBSXx/fix/fsync-pipe-fb
fix(libkernel): fail fsync and fdatasync on a pipe with EINVAL
2026-10-20 16:24:09 +13:00
Dean 28a9be72a4 Merge pull request #8182 from xXPBSXx/fix/flock-bad-descriptor-fb
fix(libkernel): fail flock on an invalid descriptor with EBADF and on a pipe with EOPNOTSUPP
2026-10-20 16:23:47 +13:00
Dean 53415f5ec6 Merge pull request #8192 from xXPBSXx/fix/fopen-directory-write-fb
fix(libc): fail fopen and freopen of a directory for writing with EISDIR on Windows
2026-10-20 16:22:17 +13:00
xXPBSXxandClaude Sonnet 5.5 d6b5e3f6b8 fix(libc): fail fopen and freopen of a directory for writing with EISDIR on Windows
fopen and freopen of a directory in a write mode failed with EACCES on
Windows, the host's answer. FreeBSD 11.4 fopen opens the path with open(2),
which fails a directory opened for writing with EISDIR (kern_openat, vn_open_cred).
A failed write-mode open of a directory now reports EISDIR.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 03:59:03 +02:00
xXPBSXxandClaude Sonnet 5.5 da6b8561c3 fix(libkernel): fail fsync and fdatasync on a pipe with EINVAL
On Windows fsync and fdatasync of a pipe descriptor answered EBADF for the
read end and 0 for the write end. FreeBSD 11.4 kern_fsync reaches the
descriptor through getvnode, which fails a descriptor that is not a vnode
with EINVAL. NativeSync now refuses a pipe handle with EINVAL before it
commits.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 03:32:02 +02:00
xXPBSXxandClaude Sonnet 5.5 a11756851e fix(libkernel): fail flock on an invalid descriptor with EBADF and on a pipe with EOPNOTSUPP
flock on a descriptor that is not open threw a runtime_error from the failed
Windows lock call, ending the title. FreeBSD 11.4 sys_flock fails it with
EBADF (fget) and a descriptor that is not a vnode, such as a pipe, with
EOPNOTSUPP. The guest flock now checks the descriptor first, on Windows
through the OS handle and elsewhere through fstat.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 03:29:01 +02:00
xXPBSXxandClaude Sonnet 5.5 dd945495e3 fix(libkernel): check truncate length and utimes times before the path
FreeBSD 11.4 kern_truncate returns EINVAL for a negative length before it
looks up the path, and getutimes rejects an out-of-range tv_usec before
namei in utimes and lutimes. The guest calls checked a NULL or empty path
first, so truncate(NULL, -1) and utimes("", {usec -1}) returned EFAULT or
ENOENT where FreeBSD returns EINVAL.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 03:07:47 +02:00
Dean 0b6486704b Merge pull request #7915 from root-over/fix/libkernel-open-flags-before-path-v2
fix(libkernel): check open flags before the path in open, _open and openat
2026-10-20 05:52:06 +13:00
Adrià 32004dfa55 Merge pull request #6992 from MarcZX10/codex/fix-stat-symlink-6983
fix(libkernel): return ELOOP when stat follows a symlink loop
2026-10-19 18:00:27 +02:00
Giuseppe Magliano ff688b2146 fix(libkernel): check open flags before the path in open, _open and openat
FreeBSD 11.4 rejects access mode 3 in kern_openat and
O_CREAT|O_EXCL|O_DIRECTORY in vn_open_cred before namei reads the path
or resolves the directory descriptor. open, _open and openat checked a
NULL or empty path first and returned EFAULT or ENOENT for those flags.
InvalidOpenFlags moves to FileFlags.hpp and runs first in all three.
2026-10-19 15:34:43 +02:00
MarcZX100 4c0767c248 test(libkernel): remove stat loop symlink fixture 2026-10-19 14:44:53 +02:00
MarcZX100 7c7a590caa fix(libkernel): map Linux stat symlink loops 2026-10-19 14:44:53 +02:00
MarcZX100 41483e7a21 fix(libkernel): return ELOOP when stat follows a symlink loop 2026-10-19 14:44:32 +02:00
LexroidandClaude Opus 5.5 4fe32a457c fix(libkernel): return EBADF from fstat on a descriptor that is not open on Windows
sceKernelFstat and fstat passed any descriptor to the UCRT's _fstat64, which
raises the invalid-parameter handler for one that is not open. The crash
report installs that handler as fatal, so the calling thread died where the
console returns EBADF. Dying Light 2 (PPSA02262) hits it on a loading thread
right after sign-in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 12:42:34 +02:00
Adrià b95ca1b87d Merge pull request #6648 from NevesHenry/fix/libkernel-open-errno-mapping
fix(libkernel): report ENAMETOOLONG and ELOOP from open, unlink and stat
2026-10-19 10:15:06 +02:00
Adrià dc54701e49 Merge pull request #6541 from wachi35676/fix/libc-fopen-random-device
fix(libc): read /dev/random and /dev/urandom through fopen
2026-10-19 08:38:06 +02:00
Adrià 79d7d26b6d Merge pull request #6484 from Ondra97/codex/team-20261015-worker-2
fix(libkernel): share guest rename semantics with sceKernelRename
2026-10-19 03:35:57 +02:00
NevesHenryandClaude Opus 5.5 3fe7ba01c3 fix(libkernel): report ENAMETOOLONG and ELOOP from open, unlink and stat
Open.cpp passed host errno values 1 to 34 through and turned every
other one into EIO. On Linux, ENAMETOOLONG (36) and ELOOP (40) are above
that range, so sceKernelOpen and sceKernelUnlink returned EIO for a name
longer than 255 bytes or a symbolic link loop, where FreeBSD returns
ENAMETOOLONG (63) and ELOOP (62). sceKernelStat returned ENOENT for
both. sceKernelMkdir already reported them through the mapping in
Stdio.cpp.

Values above 34 now go through FilesystemError, the std::errc mapping
that path resolution already uses. sceKernelStat returns ENAMETOOLONG
and ELOOP when the status query fails with them. The POSIX open, unlink
and stat wrappers set the same errno values.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 21:35:18 -03:00
Muhammad Wasif Ali WasifandClaude Opus 5.5 b4e80e8fc7 fix(libc): read /dev/random and /dev/urandom through fopen
fopen resolved the random device paths to a host file that does not
exist and failed with ENOENT, while open and sceKernelOpen already serve
them from host entropy. A read-only fopen of either path now returns a
stream whose fread fills the buffer with host entropy. setvbuf, feof,
ferror, clearerr, the stream locks and fclose work on it, fflush returns
0 as on a FreeBSD stream that is not writing, other stream functions
throw, and opening the paths for writing throws as in libkernel.

ProsperoTV (PPSA99003) reads its phone pairing code this way and showed
"Code expired or unavailable".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 03:01:38 +05:00
Dean cd20b7f6f8 Merge pull request #6132 from MarcZX10/codex/open-resolved-path-diagnostics
fix(libkernel): log resolved paths for failed opens
2026-10-19 07:22:43 +13:00
Maz e79cf0f754 fix(libkernel): stop O_NOFOLLOW from opening a Windows directory junction
lstat reports the junction as a symbolic link, but open with O_NOFOLLOW still opened the target.
2026-10-18 17:19:02 +04:00
Maz bd0caa451b Merge upstream/main into fix/windows-junction
Keep the drive-absolute junction note and the updated setitimer debt from main.
2026-10-18 12:57:10 +04:00
Maz e964264d23 Merge branch fix/windows-absolute-symlink into fix/windows-junction
Keep the junction reader and try the absolute symbolic-link reader first.
2026-10-18 12:50:08 +04:00
Dean 7cdfbd2e9d Merge pull request #7152 from Bonjourcestmatt/fix/getdents-not-directory
fix(libkernel): report EINVAL for getdirentries on a non-directory
2026-10-18 14:50:26 +13:00
MarcZX100 087c57ac84 test: retry transient Windows filesystem cleanup 2026-10-18 00:45:12 +00:00
Maz 01f3938fe1 fix(libkernel): report Windows directory junctions from lstat and readlink 2026-10-18 01:05:40 +04:00
Dean f3f622f65f Merge pull request #7196 from MarcZX100/codex/stat-long-path-7195
fix(libkernel): stat files under long Windows paths
2026-10-18 10:01:49 +13:00
MarcZX100 28eaa5bdad fix(libkernel): preserve extended paths in stat metadata 2026-10-17 16:15:54 +00:00
MarcZX100 c0a6caeed3 test(libkernel): preserve directory stat on long paths 2026-10-17 16:15:54 +00:00
MarcZX100 2644234a24 test(libkernel): keep missing long stat paths as ENOENT 2026-10-17 16:15:54 +00:00
MarcZX100 ee5ff02e7a fix(libkernel): stat files under long Windows paths 2026-10-17 16:15:54 +00:00
Ondra97 3bf3253650 fix(libc): replace Windows directories without pre-deleting targets 2026-10-17 18:08:19 +02:00
Ondra97 de2e12148e fix(libkernel): share guest rename semantics with sceKernelRename 2026-10-17 18:08:19 +02:00
mattogepetoandClaude Sonnet 5.5 9dc6542999 fix(libkernel): report EINVAL for getdirentries on a non-directory
sceKernelGetdirentries on a descriptor that is not a directory returned
ENOTDIR from the host getdents64 on Linux, and ENOTDIR for every descriptor
missing from the directory table on Windows, including invalid ones.
FreeBSD 11.4's kern_getdirentries returns EINVAL when the vnode is not a
directory.

Return EINVAL for a regular file on both hosts and EBADF for an invalid
descriptor on Windows. Test getdents and getdirentries on a regular file and
list the pipe case, which still fails with ESPIPE on Linux, in the library's
technical debt file.

Written with AI assistance (Claude).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-17 15:37:23 +02:00
pushkarreddyy a295b771eb fix(libkernel): return EFAULT from sceKernelWriteThrottlingStatus for a null status 2026-10-17 18:31:54 +05:30
Maz 6e331b3823 test(libkernel): compare absolute links by the file they name 2026-10-17 16:46:55 +04:00
Maz 6ad392dad3 fix(libkernel): report absolute Windows symbolic links
lstat and readlink aborted on an absolute symbolic link because only a relative reparse point was accepted. Read the link text, and still refuse reparse points that are not symbolic links.
2026-10-17 16:03:12 +04:00
MarcZX100 2b8e37ae0a fix(libkernel): log resolved paths for failed opens 2026-10-16 20:18:57 +00:00
Hussein Kadhim fd407e34a0 fix(libkernel): fail open with EINVAL for an invalid access mode or O_CREAT|O_EXCL|O_DIRECTORY
FreeBSD rejects an access mode of 3 in kern_openat and the combination of O_CREAT, O_EXCL and O_DIRECTORY in vn_open_cred before it looks the path up. sceKernelOpen, open and openat threw std::invalid_argument for access mode 3 and, on Windows, created the file for the second combination.

(cherry picked from commit 038a07098ef38e95fade52154847b579dcb0f9d0)
2026-10-16 14:21:23 +00:00
Dean Galvin eac8bfcfc0 fix(libc): list the directory once for a missing path that may be a relinked module
A read-only open, stat or reachability check of a missing path listed its
directory twice: once for a case-insensitive match of the name and again for
a case-insensitive match of the relinked <name>.guest.prx (#5434). Both
names are now matched in the same listing. Precedence and the ambiguous-name
errors are unchanged.
2026-10-15 13:59:12 +13:00
Adrià FranchandClaude cd0c6ed16e test(libkernel): do not stat the dangling link on Windows
stat of a dangling link reaches FillFileStat and throws on the CI toolchain; it is not part of this change.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-14 18:55:36 +02:00
Itamar Medyoni 52a3b15796 feat(libkernel): report relative symbolic links in lstat on Windows
lstat of a Windows symbolic link threw, although symlink creates links
with relative targets on Windows and readlink reads them. Report such a
link as S_IFLNK with its own identity and times and the length of its
target as st_size, through the reparse reader readlink already used,
now shared from libkernel. Links with absolute targets, junctions and
other reparse points still throw, as for readlink.
2026-10-14 18:55:31 +02:00
Dean c3bad39372 Merge pull request #5434 from milescoviello/fix/relinked-module-name-case
fix(libc): find a relinked module whose name differs in case
2026-10-14 22:41:23 +13:00
milescovielloandClaude Opus 5.5 f0c3a5c85e fix(libc): find a relinked module whose name differs in case
Borderlands 4 (PPSA01494) loads its UI library with
sceKernelLoadStartModule("/app0/prx/libRenoirCore.PS5.prx"), but ships
the module as prx/librenoircore.ps5.prx. On Linux the call fails:

    Could not load /app0/prx/libRenoirCore.PS5.prx result 0, handle result -2147352574

(0x80020002, ENOENT). Guest paths are resolved case-insensitively, but
that only finds a component that exists. With the documented layout,
app0/prx holds only the converted librenoircore.ps5.prx.guest.prx,
so the requested name resolves to itself and RelinkedModulePath then
looks for "libRenoirCore.PS5.prx.guest.prx" with its exact spelling.
Windows and macOS hosts ignore the case, so only Linux is affected.

RelinkedModulePath now falls back to the same ASCII case-insensitive
match as ResolveHostPath when the exact <name>.guest.prx is missing,
and throws for an ambiguous match as that does. dlopen,
sceKernelLoadStartModule, stat, open and sceKernelCheckReachability all
go through it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 01:31:24 +00:00