Commit Graph

63 Commits

Author SHA1 Message Date
milescoviello 0dda76b1f9 fix(libc): check for a pipe on every stream seek on Windows
The pipe check cached its first answer in the FileStream, so a stream
first used on a regular file stayed classified as a file after its
descriptor was replaced with a pipe (dup2 onto fileno(stream)), and a
later fseek reached the C runtime again and dropped buffered bytes.
fseeko and ftello now ask GetFileType on each call, as lseek on a pipe
does since #4670, and FileStream no longer keeps the state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 02:38:02 +00:00
David 7aabb9005c fix(libc): fail fseek and ftell on a pipe with ESPIPE on Windows 2026-10-13 02:38:01 +00:00
David dbbd6d582c fix(libc): append through a descriptor opened by fdopen in an append mode on Windows 2026-10-12 20:09:54 +00:00
Dean 9c99f43440
Merge pull request #4537 from coltken95/claude/sleepy-dirac-e44kw4
fix(libc): sort with FreeBSD 11's qsort so equal elements keep its order
2026-10-13 07:32:15 +13:00
Dean 57f91221c4
Merge pull request #4380 from AzazelSensei/fix/libc-stream-errors
fix(libc): return stream errors from fwrite, fread and fputs instead of throwing
2026-10-13 07:22:52 +13:00
Dean b701bc5d8d
Merge pull request #4372 from milescoviello/fix/fflush-read-stream
fix(libc): leave a stream that is reading untouched in fflush on Linux
2026-10-13 07:22:17 +13:00
Dean b538b28d8b
Merge pull request #4354 from milescoviello/fix/fopen-append-position
fix(libc): start append-mode streams at the end of the file
2026-10-13 07:18:50 +13:00
Claude ef09cda468
fix(libc): sort with FreeBSD 11's qsort so equal elements keep its order
qsort was a heapsort. It sorted correctly, but elements that compare
equal ended in a different order from FreeBSD's Bentley-McIlroy qsort,
in 18947 of 20000 random arrays with repeated keys, and below 7
elements, where FreeBSD's insertion sort keeps equal elements in
place, a heapsort does not. qsort now follows FreeBSD 11 qsort.c,
including its comparator call sequence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZWLdTjf1S57iLgn2rcaFb
2026-10-12 15:01:35 +00:00
Dean 57dc136026
Merge pull request #3936 from MarcZX100/codex/carry-fopen-s-output-null
fix(libc): clear fopen_s output on invalid arguments
2026-10-13 02:32:30 +13:00
Abdullah 7e2832475f fix(libc): return stream errors from fwrite, fread and fputs instead of throwing 2026-10-12 16:14:25 +03:00
Dean d58ba1010e
Merge pull request #4232 from MarcZX100/codex/carry-fdopen-modes-4022
fix(libc): accept FreeBSD fdopen modes
2026-10-13 01:30:04 +13:00
Dean 029c1bc17d
Merge pull request #3926 from MarcZX100/codex/carry-fclose-error
fix(libc): return fclose failures to callers
2026-10-13 01:24:43 +13:00
milescoviello 1337bd7e45 fix(libc): leave a stream that is reading untouched in fflush on Linux
fflush() passed every stream to glibc's fflush(). For a stream that is
reading, glibc seeks the descriptor back and drops the read buffer, and
with a pushed-back character it gets the position wrong: after fgetc()
returned 'a' from "abcdef\n" and ungetc('Z'), fflush() returned 0 and
the next fread() returned "bcdef\n\n". The pushed-back 'Z' was lost and
the last byte came back twice.

FreeBSD's fflush() writes out only a stream that is writing and leaves
every other stream as it is, lib/libc/stdio/fflush.c:

	if ((fp->_flags & (__SWR | __SRW)) == 0)
		retval = 0;
	else
		retval = __sflush(fp);

and __sflush():

	t = fp->_flags;
	if ((t & __SWR) == 0)
		return (0);

fflush() on Linux now returns 0 without calling the host for a stream
whose last operation was not a write (__fwriting() is 0). fflush(NULL)
and streams that are writing are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 08:00:21 +00:00
milescoviello 6a19442f12 fix(libc): start append-mode streams at the end of the file
fopen and freopen leave an "a+" stream where the host CRT puts it, at
the start of the file. On main, after fopen(file, "a+") on a 7-byte
file, ftell returns 0 and the first fgetc returns the first byte of the
file. FreeBSD seeks every append-mode stream to the end when it opens
it, so ftell returns 7 and a read before any fseek returns EOF. Code
that opens a log or save file with "a+" and tests ftell(f) == 0 to see
whether the file is new treats every existing file as empty.

FreeBSD 11.4 lib/libc/stdio/fopen.c (fopen), and the same lines in
lib/libc/stdio/freopen.c (freopen):

	if (oflags & O_APPEND) {
		fp->_flags2 |= __S2OAP;
		(void)_sseek(fp, (fpos_t)0, SEEK_END);
	}

lib/libc/stdio/flags.c sets O_APPEND for every mode that starts with 'a':

	case 'a':	/* open for appending */
		ret = __SWR;
		m = O_WRONLY;
		o = O_CREAT | O_APPEND;

fopen and freopen now seek a stream opened with an 'a' mode to the end
of the file, ignoring a failed seek as FreeBSD does. Writes still go to
the end through O_APPEND.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 02:50:07 +00:00
milescoviello 589de27c17 fix(libc): accept the fdopen modes FreeBSD accepts
fdopen only took a fixed list of 15 mode strings and failed with EINVAL
for any other, so "rt", "r+t", "re", "rbe" or "rw" gave NULL. FreeBSD's
fdopen parses the mode with __sflags (lib/libc/stdio/flags.c): after
r, w or a it takes b, +, x, e and v and stops at the first other
character ("default: known = 0;"), and only a bad first character or x
on a read-only mode fail with EINVAL. fopen and freopen already parse
modes this way through ParseFileMode (#2033).

fdopen now uses ParseFileMode as well and passes the host its normalised
mode without x, which FreeBSD's fdopen ignores.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 01:50:11 +00:00
Yunus Shaikh 0245ba7d88 fix(libc): open fopen streams with delete sharing on Windows
fopen opened its stream with _wfopen, which shares read and write
access but not delete access. While the guest held a stream open,
rename of its file failed with EIO and remove with EBUSY. POSIX rename
and remove work on open files, as on Linux and FreeBSD, and since
#3677 the descriptors sceKernelOpen returns share delete access.

fopen now creates the handle with CreateFileW sharing read, write and
delete, with the access and creation disposition of the mode, and
wraps it with _open_osfhandle and _wfdopen, keeping append mode. A
failed CreateFileW sets errno through the error mapping #3677 added to
libkernel's NativeOpen, which moves to libc as
WindowsOpenError_nid_no_patch so that both use it. freopen still
reopens through _wfreopen; TechnicalDebt records it.
2026-10-11 15:56:20 -07:00
Dean fabbeb393b
Merge pull request #3522 from pushkarreddyy/feat/libc-reallocf
feat(libc): implement reallocf
2026-10-12 11:21:30 +13:00
Santhosh Kumar 17827dd9ab fix(filesystem): reject invalid parent traversal on Windows 2026-10-12 01:25:02 +05:30
MarcZX100 cc7343daf5 fix(libc): clear fopen_s output on invalid arguments
(cherry picked from commit 387279ee941e5a203325852b24cdb87e2f835e43)
2026-10-11 19:16:51 +00:00
MarcZX100 fdf288f3fc fix(libc): return fclose failures to callers
(cherry picked from commit 610d6cdda098e9adfcd3814b52f8eba01caaa4d1)
2026-10-11 19:12:46 +00:00
pushkarreddyy 06f84010bb feat(libc): implement reallocf
Two catalog titles stop on the absent libSceLibcInternal export reallocf
(YMZO9ChZb0E) on main 0f863c10:

- PPSA97510 PSXS5 2.2.0
- PPSA98510 SwanStationPS5 1.1.3

    FAIL: unresolved ELF import YMZO9ChZb0E from libSceLibcInternal.prx

reallocf follows FreeBSD 11 lib/libc/stdlib/reallocf.c (freebsd-src
stable/11 5ed7eb0d97ba4436218e810f61bd059acba984c2) on top of the guest
realloc: it reallocates through the application heap, and when realloc
fails (the application allocator returns null or the default heap
rejects the size) it frees the block through the same allocator, sets
ENOMEM and returns null. Size 0 frees and returns null as realloc does
here, so the block is not freed twice. Other heap failures throw, as
for realloc. The NID matches tools/nid_names.py and aerolib.

The application heap tests cover grow, shrink, a null pointer, size 0
and failure with both the replacement and the default allocator.

Co-Authored-By: screamm <noreply@github.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-11 18:16:07 +05:30
Adrià Franch 859f2f3b92 feat(libc): implement malloc_usable_size
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-11 04:41:39 +02:00
Adrià Franch e7605c8fd6 feat(libc): implement rewind
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-11 02:54:24 +02:00
xXPBSXx eb18595e81 fix(libc): open fopen and freopen paths through the wide CRT on Windows 2026-10-10 21:23:30 +13:00
Scott Schuster 8bba489932 fix(libc): parse fopen and freopen modes as FreeBSD does
FreeBSD's __sflags reads the access character, then b, +, x, e and v, and
stops at the first other character without failing, so "rt" opens for
reading. On Windows fopen inserted b after the first character and passed
the rest on, so "rt" became "rbt", the CRT rejected it with EINVAL, and
fopen threw. vkQuake opens history.txt with "rt" at startup. freopen
accepted only a fixed list of modes.

Both now parse the mode like __sflags. An unknown access character, or x
on a read-only stream, returns NULL with EINVAL; x on an existing file
returns NULL with EEXIST; e and v are accepted and ignored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:48:13 -05:00
Dean 07633df7fb
Merge pull request #1549 from LeandroLP23/fix/gcc-warnings
fix: clear the GCC warnings in ProfileOutput, fopen, Ajm batch jobs and the SHA-256 test
2026-10-10 17:39:38 +13:00
LeandroLP23 2bdb979e69 fix: clear the GCC warnings in ProfileOutput, fopen, Ajm batch jobs and the SHA-256 test
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 11:37:04 +02:00
Aryan Sharma 7b130700f6 feat(libc): implement malloc_stats_fast through the application allocator
A title that replaces the allocator through its libc parameters also
supplies malloc_stats_fast in that table, and PPSA28997 calls it. It is
now forwarded to the title's function. Without a replacement allocator
that provides it, the call throws.
2026-10-09 11:04:45 +05:30
boykopovar b157046640 fix(libc): guard fread buffers with ostrite 2026-10-08 17:28:30 +03: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
Dean 9ab937b261
Merge pull request #973 from ebarr24/codex/libc-posix-memalign-errors
fix(libc): return posix_memalign allocation errors
2026-10-07 18:01:22 +13:00
Dean 9ec263cec0
Merge pull request #887 from adriadam10/feat/libc-fiopen
feat(libc): implement std::_Fiopen
2026-10-07 15:30:30 +13:00
Ethan Barr c6dde16023 fix(libc): preserve invalid allocator result diagnostics 2026-10-06 16:44:58 -07:00
Ethan Barr db49ba97b5 fix(libc): return posix_memalign allocation errors 2026-10-06 16:41:01 -07:00
Ethan Barr 34689f39ca fix(libc): preserve guest stdio bytes on Windows 2026-10-06 13:41:25 -07:00
Adrià Franch 7389b2581f feat(libc): implement std::_Fiopen
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-06 15:09:04 +02:00
Nicolas Abosch 7789c0a57b feat(libs): implement homebrew libc and kernel runtime exports 2026-10-05 22:40:16 -03:00
Dean e656baf20b
Merge pull request #398 from Pouare514/fix/libc-fopen-enoent
fix(libc): return NULL with ENOENT for missing files in fopen
2026-10-04 14:02:14 +13:00
Pouare514 92f3cb3916 fix(libc): return NULL with ENOENT for missing files in fopen 2026-10-02 22:41:57 +02:00
RomainROCH 99fbcf0377 fix(libc): propagate file position errors 2026-10-02 06:15:14 +02:00
asimplestray b42db4b6f3 feat(libc): implement RaiseEv, catchReturnFromMain and reallocalign 2026-09-30 23:55:00 +00:00
Dean Galvin a599eca727 feat(libc): operator new/delete, bounds-checked functions, char locale facets and runtime helpers
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ButHENCbXXt8h4EZuWUabJ
2026-09-28 14:22:48 +13:00
SamG-Coder 6cdf4a5be1 feat(libc): implement binary search with guest comparator ABI 2026-09-25 07:24:17 +10:00
SamG-Coder dd0debe967 feat(libc): reopen guest streams while preserving identity 2026-09-25 07:05:07 +10:00
SamG-Coder 79edb20f17 fix(libc): preserve 64-bit guest stream offsets 2026-09-25 07:00:45 +10:00
SamG-Coder e8ecb29170 feat(libc): expose guest standard streams and character IO 2026-09-25 06:30:30 +10:00
boykopovar 9f2b41b9a1 fix(libc): route guest allocations through application heap 2026-09-24 06:53:12 +03:00
boykopovar 7fa0e0c469 fix(libc): add sort function manual impl for compare abi 2026-09-22 18:35:09 +03:00
boykopovar 3028c87491 feat(agc): add bda memory mapping and resource management (wip) 2026-09-21 18:54:06 +03:00
boykopovar 3da76b9b33 refactor(graphics): add new graphics pipeline log + remove redunant ones 2026-09-18 21:03:11 +03:00