0.8.0 --- openkal 0.13: whether a node may be started, and a start that is not a program - #24
Merged
Merged
Conversation
…at is not a program kal_err_not_program maps ERROR_BAD_EXE_FORMAT and ERROR_EXE_MACHINE_TYPE_MISMATCH, this loader's two reports of a name that exists and is not a form it can start (ERROR_INVALID_EXE_SIGNATURE and ERROR_EXE_MARKED_INVALID, the same header- validation family, are mapped with them). Measured under Wine: CreateProcessW upon a text file with no recognised extension returns ERROR_BAD_EXE_FORMAT (193). kal_fs_set_executable_at is exported and does not claim KAL_FS_PROP_EXECUTABLE: this system's ordinary volumes do not record whether a node may be started, so the operation validates its arguments as its siblings do and reports kal_err_not_supported rather than simulate a property nothing here stores. kal_fs_info and kal_fs_file_info already left KAL_INFO_EXECUTABLE out of present, which needed no change. A spawn inherits only the handles it placed. CreateProcessW with inheritance enabled handed the started program every inheritable handle of this process, not only the three this operation named --- a defect independent of the specification, and the one a detached child's leaked standard output was found by: a program that kept the pipe open long after its starter had gone made whoever waited for the end of it wait for the wrong program. The fix is STARTUPINFOEXW with PROC_THREAD_ATTRIBUTE_HANDLE_LIST naming exactly the deduplicated, non-null standard handles this start placed; every other inheritable handle of the caller no longer crosses. tests/handle_inheritance.cpp proves it directly: an inheritable handle made for a reason of its own and never placed is not inherited, observed under Wine. The two directions of a connection are independent, clause 6.6. Every socket is now made with WSA_FLAG_OVERLAPPED; a synchronous handle on this system shares one completion event between whatever operations are issued upon it, so a read blocked in one context held back a write from another on the same connection, which is exactly what clause 6.6 forbids. kal_stream_read/write issue ReadFile/WriteFile with an OVERLAPPED of their own for a socket and wait for it synchronously; a file or a pipe, neither of which is overlapped, is unaffected. kal_datagram_send_to/recv_from do the same through WSASendTo/WSARecvFrom, so a datagram socket's two directions do not contend either. The conformance suite's new observation, that a write is not delayed by a read waiting on the same connection, holds. Comments carry no emoji.
…GSIZE Measured on windows-2022 (this PR's own CI): a message too large for the buffer, received through the overlapped WSARecvFrom this version introduced, completes with STATUS_BUFFER_OVERFLOW; GetOverlappedResult reports that through the generic Win32 channel as ERROR_MORE_DATA, not as the Winsock-specific WSAEMSGSIZE the immediate-failure path gives and the rest of src/datagram.cpp already checks for. The two are normalised to one where the overlapped result is read, so the truncation this interface requires to be reported as a success (the bytes that fit, not a failure) is recognised regardless of which path the completion took. Wine did not reproduce the distinction; both toolchain rows on windows-2022 did.
…ormance step beside it already does The gcc/gnu-CRT row's mcpp test, run with no --target, did not pick up [target.'cfg(all(windows, not(env = "msvc")))'.build].ldflags -- the import libraries this package's own objects need (ntdll, synchronization, bcrypt) -- and every test failed to link: undefined references to __imp_NtCreateFile, __imp_WaitOnAddress, __imp_BCryptGenRandom, and the rest, all from openkal-windows's own objects the test links against. Passing --target x86_64-windows-gnu, matching the matrix and the step beside it, resolves it: a local cross build with the same flag links and runs handle_inheritance cleanly.
Recorded after review. 0.7 made sockets synchronous so that a started program could treat one as a pipe; 0.8 makes them overlapped for the independence of the two directions. A started program that issues synchronous transfers on an inherited socket is outside what the system defines, and a caller relays the connection through a channel instead.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
kal_err_not_programmapsERROR_BAD_EXE_FORMATandERROR_EXE_MACHINE_TYPE_MISMATCH(plus the same header-validation family,ERROR_INVALID_EXE_SIGNATURE/ERROR_EXE_MARKED_INVALID). Measured under Wine:CreateProcessWupon a text file with no recognised extension returnsERROR_BAD_EXE_FORMAT(193).kal_fs_set_executable_atis exported and does not claimKAL_FS_PROP_EXECUTABLE: this system's ordinary volumes do not record whether a node may be started, so the operation validates its arguments and reportskal_err_not_supported.CreateProcessWwith inheritance enabled used to hand the started program every inheritable handle of the caller, not only the three named in the start-up record — a detached child could keep a starter's own standard output open long after the starter had gone. Fixed withSTARTUPINFOEXW+PROC_THREAD_ATTRIBUTE_HANDLE_LISTnaming exactly the deduplicated, non-null placed handles. Covered by a new test,tests/handle_inheritance.cpp.WSA_FLAG_OVERLAPPED; a synchronous handle on this system shares one completion event across operations, so a read blocked in one context held back a write from another on the same connection.kal_stream_read/kal_stream_writeandkal_datagram_send_to/recv_fromnow issue their transfers through their ownOVERLAPPEDand wait for it, so the two directions no longer contend. Files and pipes (not overlapped) are unaffected.openkaldependency 0.13.0.Verification
Local, under Wine (
wine-9.0), cross-built forx86_64-windows-gnuagainst the siblingopenkalworking tree on branchopenkal-0.13:full,exec,random,terminal,net,datagram,timeout): 174 held, 0 did not hold, 6 not observed (the 6 are volume properties this environment does not have — links, locks, executable-recording — each correctly reported asnot observedrather than failing).tests/handle_inheritance.cpp: green under the fix. I additionally revertedsrc/process.cppto the pre-fix version and re-ran the same test to attempt a red-before/green-after pair; under Wine the pre-fix version also passed — Wine's process/handle-inheritance model does not appear to reproduce this specific NT quirk (unrestrictedbInheritHandleshanding over every inheritable handle) as faithfully as real Windows does, so the regression could not be demonstrated red locally. The fix follows documented Win32 semantics and is covered by this PR'sconformancejob, which runs on nativewindows-2022runners.check-surface.sh --complete): 102 names, complete and conformant..def" check: 72 declared, 75 exported, ok.devandreleaseprofiles: both clean.mcpp.tomlverified to have no local/absolute path left in it after each of the above (the scripts' own trap-restore, checked by hand).Test plan
conformancejob (nativewindows-2022, three toolchain rows) — watching.crossjob (Wine + surface + independence) — watching.