Repository navigation
fix(libc): translate host errno from fopen, freopen and fopen_s - #7068
Conversation
fopen left the host's errno in place when the host open failed, so on Linux a symlink loop reached the title as 40 and an over-long name as 36, which are EMSGSIZE and EINPROGRESS on FreeBSD. GuestErrnoFromHost_nid_no_patch maps the host value to FreeBSD 11.4's: 1 to 34 are shared except EAGAIN (35), and ELOOP, ENAMETOOLONG, ENOTEMPTY, EDQUOT, EOVERFLOW and EDEADLK get their FreeBSD numbers; anything else is EIO.
freopen closed the stream and returned the host's errno from the failed reopen as is, with the same Linux numbers for a symlink loop or an over-long name as fopen had. It now passes it through GuestErrnoFromHost_nid_no_patch.
fopen_s returned ENOENT for every failed open, including an invalid mode, a directory opened for writing and the loop and long-name cases. C11 K.3.5.2.1 only asks for a nonzero value; Microsoft's CRT, which shares Dinkumware's library, returns errno. fopen_s now returns the errno fopen set.
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
|
Windows run of head
Titles.
No Review: no comments, no new exports or NIDs, no title-specific code. Since the symlink and long-name cases can only fail on a Linux host, a variant of the test for Windows (missing file, directory opened for writing, invalid mode, Not checked: Linux, macOS, PS5 hardware, Written with Claude Code assistance (validation by a subagent, reviewed in this session). |
What
libc's stream-opening calls passed the host's errno to the title untranslated. On Linux a symlink loop reached the title as 40 and an over-long name as 36, which are
EMSGSIZEandEINPROGRESSon FreeBSD 11.4 instead ofELOOP(62) andENAMETOOLONG(63).fopen_sreturnedENOENTfor every failure.opendir,realpath,chdir,chmod,utimes,lutimesandchflagsalready return the FreeBSD values; only thefopenfamily leaked.fix(libc):GuestErrnoFromHost_nid_no_patch(libc/src/HostErrno.cpp) maps a host errno to FreeBSD's:EAGAIN, which becomes 35;ELOOP,ENAMETOOLONG,ENOTEMPTY,EDQUOT,EOVERFLOWandEDEADLKget their FreeBSD numbers;EIO.fopenuses it. On WindowsOpenNativealready sets host values fromWindowsOpenError_nid_no_patch, so they pass through the same table.fix(libc):freopenuses the same translation for its failed reopen.fix(libc):fopen_sreturns the errnofopenset. C11 K.3.5.2.1 only requires a nonzero value; Microsoft's CRT, built on Dinkumware like the console's libc, returns errno. Recorded indocs/dev/debt/libc.mdas unverified on console.Tested
Linux x86-64, GCC.
guest_fopen_errorstest (UNIX only, since it creates symlinks):fopen,freopenandfopen_swith a self loop, a path through a loop, a 300-byte name and a path under it;file_streams,file_position,guest_fiopen(including itsfopen_schecks), access, directories,fdopendir, standard streams, working directory, host streams and statvfs.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)