Commit Graph
17 Commits
Author SHA1 Message Date
Retr0 36226741f5 fix(libc): open a directory with fopen in a read mode on Windows
FreeBSD 11 fopen opens the path with _open, and vn_open_vnode refuses a
directory only for FWRITE or O_TRUNC, so fopen of a directory in a read
mode succeeds; Linux hosts already open it. On Windows CreateFileW
without FILE_FLAG_BACKUP_SEMANTICS refused it with EACCES.

fopen now opens such a path as a libkernel directory descriptor, which
libkernel registers in libc when it loads, and fclose and freopen remove
it from libkernel's table. Reads on the stream fail with EISDIR and set
the error indicator, as on a Linux host and FreeBSD's tmpfs: the Windows
CRT fails them already but reports EINVAL. Writes fail with EBADF, and
fseek, ftell and ungetc work, as on any read-only stream.
2026-10-21 14:48:37 +03:00
Dean b77bd58806 Merge pull request #8226 from dantdmdarealguy/fix/libc-update-stream-read-windows
fix(libc): switch update streams to reading as FreeBSD does
2026-10-21 19:57:35 +13:00
Ethan Barr 4f6a37d790 fix(libc): share delete access when freopen reopens a stream onto a file on Windows
On Windows, freopen reopened a stream through _wfreopen, which opens the file without FILE_SHARE_DELETE, so remove or rename of the file failed while the stream was open, unlike fopen streams and POSIX unlink/rename of an open file. freopen now closes the previous stream and opens the new file through the same CreateFileW path fopen uses, so the reopened stream shares delete access. Host standard streams and an empty filename keep the _wfreopen path. Reference: FreeBSD 11 unlink(2) and rename(2) succeed on a file that is open.
2026-10-20 17:07:21 -04:00
dantdmdarealguy a7e6e597d3 fix(libc): switch update streams to reading as FreeBSD does
On Windows the UCRT does not switch an r+, w+ or a+ stream from writing
to reading without fflush or fseek: fread after fwrite returned bytes of
the write buffer and the next flush wrote them over the file, and ungetc
failed on an update stream that was not already reading. On Linux glibc
does not switch either for ungetc, which pushes the byte back over the
pending write, drops the write and can corrupt the heap on the next read,
or for an fread of at least the buffer size, which drops the write and
reads from the old offset.

fread, fgetc, getc_unlocked, fgets, ungetc, ungetwc and fscanf now flush
pending output and mark the stream as reading first, as FreeBSD 11.4's
__srefill and __ungetc do, through _IO_switch_to_get_mode on glibc.
Writes directly after reads still go through the UCRT on Windows; the
gap is recorded in the libc technical debt.
2026-10-20 11:28:19 -05:00
Ondra97 a70531c8fb Merge remote-tracking branch 'origin/main' into codex/fix-fiopen-exclusive-create 2026-10-16 11:22:10 +02:00
Ondra97 d902afe2d4 fix(libc): create noreplace streams exclusively 2026-10-14 18:47:19 +02:00
babyhuey 292752ff5a fix(libc): fail stream calls on a stream that a failed freopen closed 2026-10-14 02:20:06 -04:00
Dean 7e68acbb29 Merge pull request #4904 from EagleBearerYS/fix/libc-fflush-errors
fix(libc): return flush failures from fflush instead of throwing
2026-10-14 19:15:54 +13:00
MarcZX100 eefe4db018 fix(libc): return native fopen errors 2026-10-13 07:51:09 +00:00
Yunus Shaikh 3d550b3de4 fix(libc): return flush failures from fflush instead of throwing
fflush threw when the host flush failed, which ends the title on an
ordinary write error such as a full disk. FreeBSD's __sflush sets the
stream's error flag and returns EOF, as C17 7.21.5.2 asks. fflush now
returns the host result and keeps the guest stream's error flag in sync,
as fwrite, fputs and fclose already do since #4380 and #3926.
2026-10-12 19:58:04 -07:00
Abdullah 7e2832475f fix(libc): return stream errors from fwrite, fread and fputs instead of throwing 2026-10-12 16:14:25 +03: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
xXPBSXx eb18595e81 fix(libc): open fopen and freopen paths through the wide CRT on Windows 2026-10-10 21:23:30 +13:00
MarcZX100 8af7d99720 test(libc): use guest ABI in file stream test 2026-10-09 23:02:29 +00:00
MarcZX100 46b2dfab20 test(libc): avoid undefined read-only fwrite in stream test 2026-10-09 23:02:29 +00:00
MarcZX100 1374a30a2b test(libc): register file stream coverage 2026-10-09 23:02:29 +00:00
boykopovar fdd7049250 fix(libc): fix ftools exports 2026-09-07 19:54:01 +03:00