Skip to content

Commit 472be94

Browse files
authored
Record what a placed stream outlives, and the value two interfaces disagree about (#18)
Two properties of kal_spawn_streams that an implementation and a caller have had to discover by running. Neither declaration changes and neither is added to, so the surface and clause 8 are untouched. A STREAM PLACED IN A SPAWN IS THE STARTED PROGRAM'S. kal_process_channel already requires a caller to release the far end after the spawn --- a parent that does not never observes the end of input on its own --- so an implementation that did not carry the stream across would make that instruction impossible to follow. The same holds for a caller that opens a file in order to place its stream, and that caller had nothing to read. ZERO IS RESERVED IN THIS STRUCTURE AND IN NO OTHER. kal_stream has no distinguished value, and an implementation whose streams are its environment's own descriptors answers kal_stdin() with zero; openkal-linux does. The two readings agree at position `in' and cannot be told apart anywhere else, so a caller that places its own standard input at position `out' is asking for something this structure cannot express. Recorded with what a caller should do about it --- report the request as unsupported rather than pass on a word that will be read as inheritance --- and with the one thing an implementation can do to remove the ambiguity for every caller. Found by openkal-musl while answering openkal-linux#13: classifying "this descriptor has no stream" by the handle's VALUE refused every spawn, because the value zero is standard input.
1 parent 8ed32a6 commit 472be94

1 file changed

Lines changed: 35 additions & 1 deletion

File tree

include/openkal/process.h

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,41 @@ struct kal_process { kal_uintptr h; };
1717
/* How a started program's standard streams are supplied. A stream handle of
1818
* zero denotes that the program inherits the corresponding stream of its
1919
* parent, which is what an environment without a general mechanism for
20-
* passing handles can always provide. */
20+
* passing handles can always provide.
21+
*
22+
* A STREAM PLACED HERE IS THE STARTED PROGRAM'S FOR AS LONG AS THAT PROGRAM
23+
* RUNS, AND THE CALLER MAY RELEASE ITS OWN REFERENCE AS SOON AS THE SPAWN HAS
24+
* RETURNED. `kal_process_channel' below already requires this of a caller in as
25+
* many words --- a parent that does not release `theirs' after the spawn never
26+
* observes the end of input on `mine' --- so an implementation that did not
27+
* carry the stream across would make that instruction impossible to follow. It
28+
* is stated here for streams in general, because a caller that places the stream
29+
* of a file it opened for the purpose is in the same position and had nothing to
30+
* read.
31+
*
32+
* ⚠️ ZERO IS RESERVED HERE AND IS NOT RESERVED IN `openkal.stream', WHICH IS A
33+
* COLLISION AND IS RECORDED RATHER THAN REPAIRED.
34+
*
35+
* `kal_stream' has no distinguished value: an implementation whose streams are
36+
* its environment's own descriptors answers `kal_stdin()' with zero, and
37+
* openkal-linux does. The two readings agree at position `in' --- placing
38+
* standard input at standard input and inheriting it are the same act --- and
39+
* cannot be told apart anywhere else, so a caller that places its own standard
40+
* input at position `out' or `err' is asking for something this structure cannot
41+
* express.
42+
*
43+
* ⇒ A caller that cannot tolerate the ambiguity DOES NOT PASS THE VALUE: it
44+
* reports the request as unsupported, which is what a library above this
45+
* interface can act upon, rather than passing on a word that will be read as
46+
* inheritance. An implementation MAY remove the ambiguity for its own resources
47+
* by not answering any stream enquiry with zero, and one that does so removes it
48+
* for every caller.
49+
*
50+
* Repairing it in this structure would mean a second declaration --- clause 8
51+
* forbids altering this one --- and the case it would serve is a caller that
52+
* sends a program's output to its own standard input. Recorded here so that the
53+
* next implementation meets it in the specification rather than in a program
54+
* that wrote to the wrong stream. */
2155
struct kal_spawn_streams {
2256
kal_uintptr in;
2357
kal_uintptr out;

0 commit comments

Comments
 (0)