Commit Graph

89 Commits

Author SHA1 Message Date
Adrià 73e5078c3b
Merge pull request #2819 from MarcZX100/codex/mkdir-trailing-slash-2743
fix(libkernel): accept trailing slashes in sceKernelMkdir
2026-10-11 00:52:01 +02:00
David 9902f137af feat(libkernel): implement sceKernelFcntl
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit f0c649704dbf0b84077c29ea914e0e4799714fe1)
2026-10-11 00:06:02 +02:00
Hannah Lyons 0c2d85238b feat(libkernel): implement preadv and pwritev 2026-10-10 16:21:56 -04:00
Dean a8d24c7e44
Merge pull request #2910 from AchrafReyani/fix/unlink-readonly
fix(libkernel): unlink read-only files on Windows
2026-10-11 08:58:25 +13:00
Dean b78ced2b1e
Merge pull request #2858 from babyhuey/feat/libkernel-fstatfs
feat(libkernel): implement _fstatfs
2026-10-11 07:26:56 +13:00
Dean 9c5d67fbe2
Merge pull request #2478 from itsbo5/feat/libkernel-dup
feat(libkernel): implement dup and dup2
2026-10-11 07:19:54 +13:00
Dean 2ece83f4dc
Merge pull request #2129 from sktharunbalaji13-cmd/contrib/scekernel-fdatasync
feat(libkernel): implement sceKernelFdatasync
2026-10-11 07:19:45 +13:00
Achraf Reyani f45d8933f2 fix(libkernel): unlink read-only files on Windows
FreeBSD's unlink ignores the file's own permission bits, so it succeeds
on a file the guest made read-only with chmod(0400). On Windows the guest
chmod sets the read-only attribute and _wunlink then failed with EACCES,
which sceKernelUnlink and unlink reported. When the path is a regular file
without write permission, make it writable before the single _wunlink and
restore the read-only attribute if the unlink fails, as remove() does
since #2342.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 03:15:42 +09:00
Renan Pires 9a3e55b8e8 feat(libkernel): implement _fstatfs 2026-10-10 13:07:42 -04:00
MathiasDevelopes 7fe298bfab fix(libkernel): return ENOENT from sceKernelStat for unconvertible paths
A guest path whose bytes the host cannot convert to a native path made
ResolvePath throw std::filesystem::filesystem_error, which aborted the
process. No file can have such a name on the host, so stat reports
ENOENT, as for any other missing file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 18:15:59 +02:00
MarcZX100 046680da48 fix(libkernel): reject empty mkdir paths 2026-10-10 16:06:21 +00:00
MarcZX100 5837210c9f fix(libkernel): preserve mkdir error handling for trailing paths 2026-10-10 16:06:21 +00:00
Achraf Reyani 3779ffa375 fix(libkernel): accept a trailing slash in sceKernelMkdir
sceKernelMkdir checked that the parent of the resolved path exists, but
for "dir/" std::filesystem::path reports "dir" itself as the parent, so
the call failed with ENOENT and created nothing, while FreeBSD's mkdir
(and the POSIX mkdir export) accept it. Strip trailing separators first,
and report ENOTDIR when the parent exists but is not a directory.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 5f74ddba8b346e6c552cf02554d47382708206f3)
2026-10-10 16:06:21 +00:00
Tharun Balaji 57be03a4c1 fix: guard sceKernelFdatasync against guest socket descriptors
Add the guest socket descriptor guard to sceKernelFdatasync before any
native syscall, matching the existing sceKernelFchmod pattern. This
prevents high guest socket descriptors (e.g. 0x10000000) from reaching
the Windows CRT _commit, which would trigger the invalid-parameter
handler, and ensures the correct SCE error is returned on all platforms.

Refactor fdatasync_nid_postfix to delegate to sceKernelFdatasync via
PosixResult, removing the duplicated socket guard and native syscall.

Extend GuestFilesystem tests to cover:
- sceKernelFdatasync on a valid guest socket returns SCE EINVAL (0x80020016)
- sceKernelFdatasync on a closed guest socket returns SCE EBADF (0x80020009)
- sceKernelFdatasync on a high invalid descriptor (0x7fffffff) returns SCE EBADF
- closed-ordinary-descriptor tests now run on Windows (verified _commit on
  a closed descriptor returns EBADF without provoking the CRT handler)
2026-10-10 20:42:36 +05:30
virp-mta df131b9c39 fix(libkernel): maintain random device and file lock invariants in dup and dup2 2026-10-10 15:54:21 +04:00
Renan Pires fb34636f47 feat(libkernel): implement dup and dup2 2026-10-10 15:52:25 +04:00
Tharun Balaji 36bc9214cf fix(libkernel): return SCE errors from sceKernelFdatasync 2026-10-10 16:55:24 +05:30
Tharun Balaji 8839f6a1ba feat(libkernel): implement sceKernelFdatasync 2026-10-10 16:55:24 +05:30
Dean Galvin 766370108d fix(libkernel): read random devices in the Windows sceKernelPread
The Windows sceKernelPread stopped going through pread when it learned to
return errors, and with it lost the random device read, so a pread on
/dev/urandom reached ReadFile on a handle that is not a disk and failed
with ESPIPE. Read random devices first, as the Linux path does.

A pread into a read-only guest mapping now returns EFAULT instead of
throwing, matching Linux and the AIO read beside it, so the Windows
guest memory test checks for that return.
2026-10-10 23:26:37 +13:00
Hussein Kadhim 9b5be73a99 fix(libkernel): keep stat working when a handle has no file identity
Leave the Windows identity fields at their stat values when
GetFileInformationByHandle fails on a handle whose basic information
could be read, instead of failing the whole call.
2026-10-10 11:08:10 +02:00
Hussein Kadhim 0b1941b313 fix(libkernel): report a stable file identity from stat and fstat on Windows
st_ino was always 0 and st_dev differed between stat (drive number) and
fstat (0), so the usual a.st_dev == b.st_dev && a.st_ino == b.st_ino
identity check gave wrong answers. Read the volume serial, the file index
and the link count from the file handle, which works the same for path and
descriptor lookups.

Fixes #2296
2026-10-10 11:08:09 +02:00
Doston Abdullayev 1fd723f21f fix(libkernel): return errors from file operation failures
On Windows, sceKernelPread and sceKernelPwrite called the POSIX pread and
pwrite wrappers, which throw on every failure, so a bad descriptor, a
negative offset or a write to a read-only descriptor aborted the process
instead of returning an error as the Linux build does. ftruncate and
sceKernelFtruncate threw on any host failure on both platforms.

Give the Windows sceKernelPread and sceKernelPwrite the same checks and
SceErrorFromErrno returns as the Linux ones, and accept a zero-length
transfer with a null buffer. Report a positioned transfer on a handle
opened without the needed access as EBADF instead of EIO. Return EINVAL
from ftruncate for a negative length and for a descriptor opened without
write access, as FreeBSD does, and pass other host errors to the guest.

Fixes #2423
2026-10-10 21:23:30 +13:00
MathiasDevelopes 7810f8464e feat(libkernel): open /dev/random and /dev/urandom for reading
Neither existed under the guest root, so opening them failed and titles
that then read from the descriptor crashed. Opening either for reading
now returns a descriptor whose reads, positioned reads and vector reads
fill the buffer from the host's random device, as
sceRandomGetRandomNumber does. Opening them for writing throws.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 09:12:55 +02:00
Dean 01dc5c14a3
Merge pull request #1764 from Zurisen/fix/flock-nonblocking-contention
fix(libkernel): return EWOULDBLOCK from a contended LOCK_NB flock
2026-10-10 20:08:00 +13:00
Adrià 7d94990371
Merge pull request #2300 from AchrafReyani/fix/libkernel-stat-trailing-slash
fix(libkernel): report ENOTDIR from stat for a file with a trailing slash
2026-10-10 08:27:27 +02:00
Adrià 473e64bc8c
Merge pull request #1860 from overlordxrz-source/feat/libkernel-shm-open
feat(libkernel): implement shm_open for anonymous objects
2026-10-10 08:07:24 +02:00
Zurisen 0f770d2203 fix(libkernel): return EWOULDBLOCK from a contended LOCK_NB flock
flock_nid_postfix threw on every failure, so a LOCK_NB request on a lock
held through another descriptor ended the process. FreeBSD flock(2)
returns -1 with EWOULDBLOCK there. Return guest errno 35 when LOCK_NB is
set and the host reports the lock as held: ERROR_LOCK_VIOLATION on
Windows, EWOULDBLOCK on Linux. Other failures still throw.
2026-10-10 07:55:48 +02:00
Zurisen d2b8e66c09 fix(libkernel): decode flock operations as FreeBSD does
FreeBSD sys_flock takes LOCK_UN over LOCK_EX over LOCK_SH, ignores other
bits and fails with EBADF when none of the three is set. The operation
reached the host unchanged, so malformed operations differed between
hosts: Linux rejects them with EINVAL and the Windows lock tracking threw.
Decode the operation before either host sees it.
2026-10-10 06:49:20 +02:00
Zurisen 6daf7df9ae fix(libkernel): give flock BSD semantics on Windows
flock mapped each call straight onto LockFileEx/UnlockFileEx, whose
byte-range locks stack per handle. LOCK_UN without a lock failed with
ERROR_NOT_LOCKED and aborted the process, a repeated LOCK_EX blocked
forever, converting between shared and exclusive failed, and a repeated
LOCK_SH needed as many unlocks.

Track the one lock each descriptor holds: a repeated mode and LOCK_UN
without a lock succeed, a conversion releases the old lock before taking
the new one, and close forgets the descriptor's lock.
2026-10-10 06:49:20 +02:00
Dean 65bd2f778a
Merge pull request #2289 from AchrafReyani/fix/libkernel-unlink-directory-eperm
fix(libkernel): return EPERM when unlinking a directory
2026-10-10 17:46:40 +13:00
Dean a8ce7b7e21
Merge pull request #1727 from SleglJan/feat/libkernel-socket-read-write
fix(libkernel): read and write guest sockets
2026-10-10 17:41:03 +13:00
Dean 7879d89f81
Merge pull request #1628 from babyhuey/fix/libkernel-open-directory-flags
fix(libkernel): honour open flags when Windows falls back to a directory descriptor
2026-10-10 17:39:54 +13:00
Achraf Reyani 610ffbbeba fix(libkernel): report ENOTDIR from stat for a file with a trailing slash
On Windows the existence check accepts "file/", then _wstat64 rejects
it and FillFileStat throws, aborting the title. On Linux the host
reports ENOTDIR, which became ENOENT. A trailing slash on something
that is not a directory now returns ENOTDIR on both hosts, as on
FreeBSD.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:14:41 +02:00
overlordxrz-source e607b1ce4e feat(libkernel): implement shm_open for anonymous objects 2026-10-09 22:05:57 -04:00
Dean c963432db0
Merge pull request #1645 from XairRrR/fix/raise-open-file-limit
fix(libkernel): raise the open file soft limit on Linux
2026-10-10 14:44:55 +13:00
Hannah Lyons 94a33bfa5c fix(libkernel): honour open flags when Windows falls back to a directory descriptor 2026-10-09 21:22:23 -04:00
ArjenS-LA 705e49d407 fix(libkernel): preserve Windows file timestamp precision 2026-10-10 01:51:56 +02:00
Raihan Abdul Majid e768d97949 fix(kernel): keep the file offset in Windows AIO reads and writes
Each Windows AIO request is an overlapped ReadFile/WriteFile at the
request's offset, which on a synchronous handle also moves the
descriptor's file pointer; on the console AIO transfers leave it alone.
The requests now go through the positioned path sceKernelPread and
sceKernelPwrite use (NativePositioned in Stdio.cpp, exposed as
NativePositioned_nid_no_patch), which restores the pointer afterwards.
Negative offsets still fail with EINVAL before the transfer.

GuestAio sets the offset to 2 before a write batch and checks it is
still 2 after. TechnicalDebt records that a concurrent read or write on
the same descriptor can see the moved pointer in between, as for the
pread family.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UTjpbMX7BUFMZZaxJE98zV
2026-10-10 00:22:22 +02:00
Jan Šlégl 9d0b105771 fix(libkernel): read and write guest sockets
read, write, _read and _write on a guest socket descriptor went to the
host, which has no such descriptor, so sceKernelRead and sceKernelWrite
threw. They now reach the socket as recv and send without flags, with
the socket layer's errno (EAGAIN 35, EPIPE 32, EBADF 9), a zero-length
read returns 0 as dofileread does, and the two sceKernel forms return
the kernel error for the same cases. The host's SIGPIPE on EPIPE, a
write above INT_MAX bytes, readv, writev and the positioned forms are
recorded in TechnicalDebt.

OpenSSL's QUIC notifier signals its socketpair with write and read.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 23:57:33 +02:00
Adrià 72cf6c3c5a
Merge pull request #1624 from babyhuey/feat/libkernel-lstat
feat(libkernel): implement lstat
2026-10-09 23:52:02 +02:00
Adrià 830130aa00
Merge pull request #1620 from babyhuey/feat/libkernel-fdatasync
feat(libkernel): implement fdatasync
2026-10-09 23:50:45 +02:00
Adrià 3d19932caf
Merge pull request #1738 from SleglJan/feat/libkernel-termios
feat(libkernel): implement tcgetattr and tcsetattr
2026-10-09 23:48:53 +02:00
Hannah Lyons 903f50a3b4 feat(libkernel): implement lstat 2026-10-09 17:30:43 -04:00
Hannah Lyons 6768210713 feat(libkernel): implement fdatasync 2026-10-09 17:30:24 -04:00
Jan Šlégl 14cc6497d2 feat(libkernel): implement tcgetattr and tcsetattr
A title's descriptors are taken as never being terminals: a file or
pipe gets ENOTTY with the termios untouched, a socket gets what its
protocol answers a termios ioctl on FreeBSD (EADDRNOTAVAIL for AF_INET,
EOPNOTSUPP otherwise), and a closed or invalid descriptor EBADF.
tcsetattr gives EINVAL for an action other than TCSANOW, TCSADRAIN or
TCSAFLUSH, with or without TCSASOFT, before anything else, and EFAULT
for a null termios before the descriptor is checked; with TCSASOFT a
null termios throws, where FreeBSD's libc faults copying it. What the
console gives a title as descriptors 0 to 2 is unknown, as recorded in
TechnicalDebt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 23:17:12 +02:00
Hannah Lyons d6963f46d6 feat(libkernel): implement getdents and getdirentries 2026-10-09 13:30:45 -04:00
Achraf Reyani 275163277b fix(libkernel): return EPERM when unlinking a directory
FreeBSD's unlink(2) reports EPERM for a directory, but the host call
returns EACCES on Windows and EISDIR on Linux, so the guest saw a
different error on each host. Check for a directory, not following a
symbolic link, before unlinking.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:39:50 +09:00
XairRrR df3aa1a9db fix(libkernel): raise the open file soft limit on Linux
Each direct memory backing keeps a memfd open, so a title such as
Dreaming Sarah (PPSA02929) holds about 1100 descriptors at startup.
With the systemd default soft limit of 1024, later opens fail with
EMFILE: memfd_create throws "create direct memory backing: Too many
open files", or the title's fopen returns NULL and it faults in fread.

libkernel now raises the RLIMIT_NOFILE soft limit to the hard limit
when it is loaded, before the title creates any descriptor, and throws
if the limit cannot be read or raised.
2026-10-08 17:38:48 +02:00
Adrià fe9beae001
Merge pull request #1452 from mrk1987/fix/posix-mkdir-errors
fix(libkernel): return POSIX errors from mkdir
2026-10-08 16:09:37 +02:00
kjhq bb1a4cbec4 fix(libkernel): flush only the paths the guest changed in sceKernelSync on Windows
Opening a volume needs administrator rights, so the volume flush skipped
every volume in a normal user session. The libc, libkernel, save data and
app content file functions now record each host file and directory they
change. On Windows sceKernelSync flushes the recorded paths that changed
since the previous call, plus their changed parent directories, through
handles a normal user can open. Linux still calls sync().
2026-10-08 08:27:22 +00:00