Provide net, datagram, timeout and exec; decline space in terms - #14
Merged
Conversation
This implementation declined all five interfaces openkal 0.8 added. Four of them this system has, and the fifth it does not --- which is a legitimate outcome rather than a gap, and is now stated as one. src/net.cpp Winsock.⚠️ `WSASocketW' with a flags word of zero rather than `socket': the latter makes an OVERLAPPED handle, upon which `ReadFile' returns before the bytes have arrived. A non-overlapped socket is what lets a connection BE a stream here --- openkal.stream is `ReadFile' and `WriteFile' on this system --- with no second transfer path. A change to that one zero would neither fail to compile nor fail to link. src/datagram.cpp the same calls with SOCK_DGRAM.⚠️ This system reports a truncated message as a FAILURE where the other two truncate silently; the bytes that fit are delivered either way, and the interface states that the excess is lost. src/timeout.cpp `WSAPoll', which answers for sockets and for nothing else. A bounded transfer upon a stream that is not a socket reports kal_err_not_supported, which the interface's own header anticipates in terms. `kal_timeout_wait_process' is the one operation of this interface the system provides DIRECTLY. src/exec.cpp VirtualAlloc, VirtualProtect, FlushInstructionCache. The third is not optional. openkal.space stays declined. `CreateProcessW' starts a NAMED PROGRAM, which is openkal.process and a different operation; constructing a copy of the calling address space out of it would be the simulation clause 3.1 forbids. A program that calls `kal_space_start' fails at the link naming the operation, which is clause 6.1's report.⚠️ THREE CONSTANTS DIFFER FROM THE OTHER SYSTEMS' WITHOUT ANNOUNCING IT: AF_INET6 is 23 here, 30 on macOS and 10 on Linux; SOL_SOCKET is 0xffff here and on macOS and 1 on Linux; and this system's `poll' has no bit named POLLIN --- what it has is POLLRDNORM, and the Linux value asks about out-of-band data instead.⚠️ ⚠️ AND THE CONFORMANCE RUN WAS SELECTING LESS THAN ITS STEP NAME SAID. `full' expands to the HOSTED set, so every optional interface --- random and terminal included, which this implementation has provided since before 0.8 --- was compiled with its section body removed and reported as not examined. The set is now enumerated: the six this system provides, and not `optional', because `optional' names `space'. Measured here rather than remembered: 16 objects, exported surface complete and conforming at 88 names, and no undefined symbol outside the permitted set.
⚠️ ⚠️ THIS SYSTEM'S NETWORK LIBRARY EXPORTS THE BSD NAMES, AND SO DOES THE C LIBRARY ABOVE THIS IMPLEMENTATION. openkal-musl compiles musl's own `src/network/*.c', which define `bind', `listen', `accept' and `connect' and route them through this port. Naming `-lws2_32' on the link line put both definitions in one program: ld.exe: libws2_32.a(libws2_32s00165.o): multiple definition of `connect'; musl/src/network/connect.o: first defined here Measured on the GNU/PE row of the C library's own continuous integration, on the first run of this change. It is not an ordering problem: an import library's member defines the thunk AND the `__imp_' pointer together, so reaching for either brings both. ⭐ THE NAMES ARE THEREFORE REACHED THROUGH THE SYSTEM'S OWN LOADER --- `LoadLibraryW' and `GetProcAddress', both of which this package already links --- into a table resolved once. Nothing of ws2_32 enters the program's symbol table, so the C library above keeps its `bind' and this implementation still reaches the system's. `port/ws2_32.def', the `-lws2_32' flag and the `#pragma comment' all come out. The table is resolved ENTIRELY OR NOT AT ALL: a table with one null entry would make the operations that resolved work and the one that did not call through zero, which is the failure clause 6.1 exists to turn into a link error and this arrangement cannot. Measured here after the change: `examples/cross-hello' links and produces `cross-hello.exe' over this implementation and that C library; 16 objects; exported surface complete and conforming at 88 names; no undefined symbol outside the permitted set; and NO BSD NAME DEFINED in this package's own objects, which is the property the collision was about.
Two failures, both from the conformance run this change made selective.⚠️ `VirtualAlloc', `VirtualProtect', `VirtualFree' and `FlushInstructionCache' were declared in src/win32.h and exported by no `.def'. This package's own check says so in as many words --- "declared in src/win32.h and exported by no .def" --- and it is the check that exists because an import library here is a list of names rather than code, so a name absent from the list is a link that finds nothing on a machine without a vendor SDK.⚠️ ⚠️ AND `kal_timeout_read' UPON THE STANDARD INPUT HAD TWO REFUSALS WHERE THE INTERFACE HAS ONE. An earlier form answered a null or invalid handle with `kal_err_invalid' and a valid non-socket with `kal_err_not_supported'; a run whose standard input is not attached has a handle of zero, so both bounded reads in the suite were reported as not holding. ⭐ The early return was answering a DIFFERENT QUESTION. "Is this handle valid" is what the unbounded operation answers. What this interface answers is whether this implementation can bound an operation upon this resource, and timeout.h sanctions exactly one refusal for that: "AN IMPLEMENTATION MAY PROVIDE THIS FOR SOME OF ITS RESOURCES AND NOT OTHERS, and reports kal_err_not_supported for the rest." A handle that is not a socket is one of the rest, and zero is not a socket. The name/export reading is also performed here before pushing, so that a round is not spent discovering a fifth name: 49 declared, 55 exported, none missing.
⚠️ `WSAPoll' takes sockets and nothing else, so `kal_timeout_read' upon a pipe reported `kal_err_not_supported' --- and `openkal.process' makes a channel out of a pipe on this system. A C library above this implementation therefore reaches `poll' and `select' upon one, and openkal-musl's network probe reported it on the row that builds for this system: FAIL: select reports the read end ready (errno=38) A `select' that refuses a pipe makes every program waiting on a subprocess's output stop. ⭐ THREE ENQUIRIES, ONE PER KIND OF OBJECT, chosen by asking what the handle is: `WSAPoll' for a socket, `PeekNamedPipe' for a pipe, and always ready for a file, because a read from one does not wait.⚠️ A socket also reports `FILE_TYPE_PIPE', so the socket enquiry is made FIRST and the file type only decides what a non-socket is. ⭐ `PeekNamedPipe' is the one NON-DESTRUCTIVE readiness enquiry in this whole ecosystem: it reports how many bytes are there and takes none, which is why this implementation needs no read-ahead where the port above it does.⚠️ A closed writing end is READY and not an error --- the call then fails with `ERROR_BROKEN_PIPE' and the read that follows reports the end of input without waiting, which is what readiness asserts. Reporting the failure would make a program that reads until end-of-input wait for ever instead. What remains unbounded is a character device, and `kal_err_not_supported' is what timeout.h states for a resource an implementation does not cover. Measured here: 16 objects, exported surface complete at 88 names, no undefined symbol outside the permitted set, 50 declared names and none missing from a `.def'.
⚠️ ⚠️ MEASURED TWICE, THE SECOND TIME ONLY UNDER WINE, WHICH IS WHAT MADE THE SHAPE VISIBLE. `kal_timeout_read' upon the standard input reported an error belonging to the RESOURCE where the interface defines a set for the WAIT: first `kal_err_invalid' for a handle of zero, then whatever `PeekNamedPipe' or `WSAPoll' had failed with. The conformance suite reported "a bounded read reports success, an expiry, or a refusal" as not holding both times, and the second time on one runner out of three --- which is to say, only where the system chose a different error for the same condition. ⇒ `await_stream' now answers with `kal_ok', `kal_err_again' or `kal_err_not_supported' and nothing else. An error belonging to the resource is the TRANSFER's to report, and the transfer follows the wait. ⭐ AND THE REAL ERROR IS KEPT WHERE THE RESOURCE IS KNOWN. `kal_timeout_accept' and `kal_timeout_recv_from' are reached with a socket this implementation made, so a failure there carries information a caller can act upon; the narrowing happens only on the path that takes a caller's stream, where the resource is not known.⚠️ `is_socket' also stops depending on WHICH error a system reports for a handle that is not a socket. It read "it is a socket unless the failure was WSAENOTSOCK", and Wine does not choose the same value. Every socket this implementation hands out has been connected, bound or accepted, so `getsockname' succeeds upon all of them; the test is that it succeeds.
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.
This implementation declined all five interfaces openkal 0.8 added. Four of
them this system has, and the fifth it does not — which is a legitimate
outcome rather than a gap, and is now stated as one.
src/net.cppsrc/datagram.cppSOCK_DGRAMsrc/timeout.cppWSAPoll, which answers for sockets and for nothing elsesrc/exec.cppVirtualAlloc,VirtualProtect,FlushInstructionCache⭐⭐
WSASocketWwith a flags word of zero, and that zero is load-bearingThe ordinary
socketmakes an overlapped handle, upon whichReadFilereturns before the bytes have arrived. A flags word of zero makes one that is
not — and that is what lets a connection be a stream here, because
openkal.streamon this system isReadFileandWriteFile. Without it thisimplementation would need a second transfer path.
A change to that one zero would neither fail to compile nor fail to link.
src/win32.handport/ws2_32.defboth say so beside the name.openkal.spacestays declined, in termsCreateProcessWstarts a named program, which isopenkal.processand adifferent operation. Constructing a copy of the calling address space out of it,
plus a mechanism for carrying the caller's memory across, would be the
simulation clause 3.1 forbids: present, shaped like the operation, and producing
something that is not a copy of the caller.
A program that calls
kal_space_starttherefore fails at the link, namingthe operation, which is clause 6.1's report and the loudest one available.
AF_INET6is 23 here, 30 on macOS, 10 on Linux.SOL_SOCKETis 0xffffhere and on macOS, 1 on Linux. And this system's
pollhas no bit namedPOLLIN— what it has isPOLLRDNORM, and the Linux value asks aboutout-of-band data instead.
Two behavioural differences are recorded rather than smoothed over:
SO_REUSEADDRis not the same option here. On the other two it permits alistener whose predecessor is lingering; here it permits two listeners on one
address at once. It is therefore not set — setting it for symmetry would make
this implementation behave differently while looking the same.
elsewhere. The bytes that fit are delivered either way, and the interface states
that the excess is lost.
fullexpands to the hosted set, so every optional interface —randomandterminalincluded, which this implementation has provided since before 0.8 —was compiled with its section body removed and reported as not examined.
The set is now enumerated: the six this system provides, and not
optional,because
optionalnamesspaceand a set demanding it would fail to linkrather than report an observation.
Measured here rather than remembered
16 objects; exported surface complete and conforming at 88 names (the two
absent are
openkal.space's, and--completeis checked group by group); noundefined symbol outside the permitted set.
This is one change across seven repositories, and every branch carries the
same name. Each repository's continuous integration substitutes its siblings'
working trees taken from the branch of the name under test, so the graph only
holds together when they agree.
openkal-muslopenkal-macosopenkal-windowsopenkal.spacedeclined in termsopenkal-linuxopenkal-llvm-runtime__config_site's claims asserted by a program, and the C library repinnedopenkalsbaseThe specification does not change. No interface was added, none was altered,
and
SURFACE.txtis untouched — every capability below is composed from atomsopenkal 0.8 already had.