kubkon edited PR #1561 from handle-rights to master:
This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are:OsFile,OsDir,Stdio,
andOsOther. Those primitives are separate structs now, each implementing
a subset ofHandlemethods, rather than all being an enumeration of some
supertype such asOsHandle. To summarise the structs:
OsFilerepresents a regular file, and implements fd-ops
ofHandletrait
OsDirrepresents a directory, and primarily implements path-ops, plus
readdirand some common fd-ops such asfdstat, etc.
Stdiorepresents a stdio handle, and implements a subset of fd-ops
such asfdstat_and_read_andwrite_vectoredcalls
OsOthercurrently represents anything else and implements a set similar
to that implemented byStdioThis commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.Some more minor changes include making
OsHandlerepresent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, sinceOsDir
is tricky across OSes, we also have a supertype ofOsHandlecalled
OsDirHandlewhich may store aDIR*stream pointer (mainly BSD). Last but not
least, theFiletypeandRightsare now computed when the resource is created,
rather than every time we callHandle::get_file_typeandHandle::get_rights.
Finally, in order to facilitate the latter, I've convertedEntryRightsinto
HandleRightsand pushed them into eachHandleimplementor.
kubkon updated PR #1561 from handle-rights to master:
This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are:OsFile,OsDir,Stdio,
andOsOther. Those primitives are separate structs now, each implementing
a subset ofHandlemethods, rather than all being an enumeration of some
supertype such asOsHandle. To summarise the structs:
OsFilerepresents a regular file, and implements fd-ops
ofHandletrait
OsDirrepresents a directory, and primarily implements path-ops, plus
readdirand some common fd-ops such asfdstat, etc.
Stdiorepresents a stdio handle, and implements a subset of fd-ops
such asfdstat_and_read_andwrite_vectoredcalls
OsOthercurrently represents anything else and implements a set similar
to that implemented byStdioThis commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.Some more minor changes include making
OsHandlerepresent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, sinceOsDir
is tricky across OSes, we also have a supertype ofOsHandlecalled
OsDirHandlewhich may store aDIR*stream pointer (mainly BSD). Last but not
least, theFiletypeandRightsare now computed when the resource is created,
rather than every time we callHandle::get_file_typeandHandle::get_rights.
Finally, in order to facilitate the latter, I've convertedEntryRightsinto
HandleRightsand pushed them into eachHandleimplementor.
kubkon updated PR #1561 from handle-rights to master:
This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are:OsFile,OsDir,Stdio,
andOsOther. Those primitives are separate structs now, each implementing
a subset ofHandlemethods, rather than all being an enumeration of some
supertype such asOsHandle. To summarise the structs:
OsFilerepresents a regular file, and implements fd-ops
ofHandletrait
OsDirrepresents a directory, and primarily implements path-ops, plus
readdirand some common fd-ops such asfdstat, etc.
Stdiorepresents a stdio handle, and implements a subset of fd-ops
such asfdstat_and_read_andwrite_vectoredcalls
OsOthercurrently represents anything else and implements a set similar
to that implemented byStdioThis commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.Some more minor changes include making
OsHandlerepresent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, sinceOsDir
is tricky across OSes, we also have a supertype ofOsHandlecalled
OsDirHandlewhich may store aDIR*stream pointer (mainly BSD). Last but not
least, theFiletypeandRightsare now computed when the resource is created,
rather than every time we callHandle::get_file_typeandHandle::get_rights.
Finally, in order to facilitate the latter, I've convertedEntryRightsinto
HandleRightsand pushed them into eachHandleimplementor.
pchickey submitted PR Review.
pchickey submitted PR Review.
pchickey created PR Review Comment:
This is maybe a comment for the PR that introduced
Handle, but if instead of having anas_any(&self) -> &dyn Any, theHandletrait instead depended onAny, then you could drop that trivial method, and also this'static' constraint, becauseAnyimplies'static`.
pchickey created PR Review Comment:
I think its pretty dangerous to panic here - instead, can we return a Result, so we can bubble this error outwards without crashing?
pchickey created PR Review Comment:
Can you leave a comment specifically on why we have to handle the tty and non-tty cases separately? Whether
io::stdout()gives us a tty or not depends on how the embedding process is invoked, right? Is there any way to avoid exposing that to the guest?
kubkon submitted PR Review.
kubkon created PR Review Comment:
Agreed! I'll redo it returning a
Resultinstead as suggested :-)
kubkon submitted PR Review.
kubkon created PR Review Comment:
Oh nice, I didn't think of that! Lemme give it a spin and report back. Oh, and thanks for the suggestion!
kubkon submitted PR Review.
kubkon created PR Review Comment:
Yeah, that's correct. I actually need to revisit at some point, but the reason we ended up with custom
Stdiotype which is a proxy for Rust's stdio handles, is because Windows was doing some crazy stdio redirects on the CI which were nontrivial to handle. I'll add some comments about for posterity. Thanks for spotting that one!
iximeow submitted PR Review.
iximeow created PR Review Comment:
drops in This is just a
&File -> ManuallyDrop<File>conversion, right? You ought to be able to remove this line (and theAsFileimpl above, it seems?
kubkon updated PR #1561 from handle-rights to master:
This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are:OsFile,OsDir,Stdio,
andOsOther. Those primitives are separate structs now, each implementing
a subset ofHandlemethods, rather than all being an enumeration of some
supertype such asOsHandle. To summarise the structs:
OsFilerepresents a regular file, and implements fd-ops
ofHandletrait
OsDirrepresents a directory, and primarily implements path-ops, plus
readdirand some common fd-ops such asfdstat, etc.
Stdiorepresents a stdio handle, and implements a subset of fd-ops
such asfdstat_and_read_andwrite_vectoredcalls
OsOthercurrently represents anything else and implements a set similar
to that implemented byStdioThis commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.Some more minor changes include making
OsHandlerepresent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, sinceOsDir
is tricky across OSes, we also have a supertype ofOsHandlecalled
OsDirHandlewhich may store aDIR*stream pointer (mainly BSD). Last but not
least, theFiletypeandRightsare now computed when the resource is created,
rather than every time we callHandle::get_file_typeandHandle::get_rights.
Finally, in order to facilitate the latter, I've convertedEntryRightsinto
HandleRightsand pushed them into eachHandleimplementor.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Ah, well spotted, thanks!
As far as the
AsFileimpl goes, this blanket impl is needed so that any type that wrapsOsHandle(which itself implementsAsRawFd) to be able to convert automatically tostd::fs::File.
kubkon submitted PR Review.
kubkon created PR Review Comment:
That's why, if you look closely, the impl goes for any
T: AsRawFd.
kubkon updated PR #1561 from handle-rights to master:
This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are:OsFile,OsDir,Stdio,
andOsOther. Those primitives are separate structs now, each implementing
a subset ofHandlemethods, rather than all being an enumeration of some
supertype such asOsHandle. To summarise the structs:
OsFilerepresents a regular file, and implements fd-ops
ofHandletrait
OsDirrepresents a directory, and primarily implements path-ops, plus
readdirand some common fd-ops such asfdstat, etc.
Stdiorepresents a stdio handle, and implements a subset of fd-ops
such asfdstat_and_read_andwrite_vectoredcalls
OsOthercurrently represents anything else and implements a set similar
to that implemented byStdioThis commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.Some more minor changes include making
OsHandlerepresent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, sinceOsDir
is tricky across OSes, we also have a supertype ofOsHandlecalled
OsDirHandlewhich may store aDIR*stream pointer (mainly BSD). Last but not
least, theFiletypeandRightsare now computed when the resource is created,
rather than every time we callHandle::get_file_typeandHandle::get_rights.
Finally, in order to facilitate the latter, I've convertedEntryRightsinto
HandleRightsand pushed them into eachHandleimplementor.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Done in 26c894a.
kubkon submitted PR Review.
kubkon created PR Review Comment:
The line removed in 5b7e54e BTW.
kubkon submitted PR Review.
kubkon created PR Review Comment:
OK, so after some careful analysis, I believe we'll still require
as_any(&self) -> &dyn Anymethod defined in each implementor of theHandletrait. Here's the breakout of the reasons I discovered:
- vtables in Rust currently do not permit for trait upcasting (see here and here). This then implies that, even if
Handle: Any, we can't go fromdyn Handletodyn Any.- Even if we added the constraint
Handle: Anyand madeas_any(&self) -> &dyn Anya provided method, we'd still need to require that, at the very least, foras_any(...)Self: Sized. But then,as_any(...)is not available fordyn Handletrait object.All in all, requiring
AnyonHandleseems to only get rid of the'staticrequirement in the referencedimpl AsFilewhich I don't think is worth it? Lemme know what you think! Maybe there's something obvious that I missed and this will actually work, or perhaps I misunderstood what you meant! :-)
kubkon created PR Review Comment:
Just clarify further, as far as the guest is concerned,
Stdioshould be transparent to them. As I mentioned above, the only reason we have a separateStdiotype inwasi-commonis to correctly facilitate redirects on Windows. To elaborate further, in POSIX, we can get a stdio handle by opening a specific fd{0,1,2}. On Windows however, we need to issue a syscall that's separate from standard Windows "open" to get a console handle, and this isGetStdHandle. This is exactly what Rust does and what is wrapped inside theirStdioobject in thelibstd. We wrap it here as well because of this nuance on Windows:The standard handles of a process may be redirected by a call to SetStdHandle, in which case GetStdHandle returns the redirected handle.
The MSDN also says this however:
If the standard handles have been redirected, you can specify the CONIN$ value in a call to the CreateFile function to get a handle to a console's input buffer. Similarly, you can specify the CONOUT$ value to get a handle to a console's active screen buffer.
But I'm not that well versed in Windows programming to know how to do this properly, which is not to say we shouldn't (re-)investigate at some point.
Anyway, do you think this explanation would do here? Oh, and as far as the check for
TTYgoes, I'm actually not sure what to do here. I'm not sure whether the handle returned byGetStdHandlewill be treated like aTTY. I guess we should investigate further, but I'd vouch for leaving a TODO comment in and do it in a subsequent PR?
kubkon submitted PR Review.
kubkon updated PR #1561 from handle-rights to master:
This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are:OsFile,OsDir,Stdio,
andOsOther. Those primitives are separate structs now, each implementing
a subset ofHandlemethods, rather than all being an enumeration of some
supertype such asOsHandle. To summarise the structs:
OsFilerepresents a regular file, and implements fd-ops
ofHandletrait
OsDirrepresents a directory, and primarily implements path-ops, plus
readdirand some common fd-ops such asfdstat, etc.
Stdiorepresents a stdio handle, and implements a subset of fd-ops
such asfdstat_and_read_andwrite_vectoredcalls
OsOthercurrently represents anything else and implements a set similar
to that implemented byStdioThis commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.Some more minor changes include making
OsHandlerepresent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, sinceOsDir
is tricky across OSes, we also have a supertype ofOsHandlecalled
OsDirHandlewhich may store aDIR*stream pointer (mainly BSD). Last but not
least, theFiletypeandRightsare now computed when the resource is created,
rather than every time we callHandle::get_file_typeandHandle::get_rights.
Finally, in order to facilitate the latter, I've convertedEntryRightsinto
HandleRightsand pushed them into eachHandleimplementor.
kubkon submitted PR Review.
kubkon created PR Review Comment:
OK, after careful analysis, I think we can remove the check and _always_ santise the output to
stdoutsinceis_ttywill always resolve to true forStdiohandle type. However, I think we need to keep the check in case ofOsOtherhandle type which can encapsulate user-specified handle to redirected stdio. I'm thinking here of piping and mainly on Unix, but perhaps it might also be possible on Windows.I've done that now in f76e7c4.
kubkon requested alexcrichton, pchickey, peterhuene and sunfishcode for a review on PR #1561.
pchickey submitted PR Review.
pchickey created PR Review Comment:
I had no idea that trait upcasting was not allowed. That is a bummer and a sufficient reason for this design.
pchickey submitted PR Review.
pchickey created PR Review Comment:
Thanks, I understand this a lot better now. Thanks for the explanation and adding it to the docs!
pchickey submitted PR Review.
kubkon submitted PR Review.
kubkon created PR Review Comment:
I didn't either, so thanks for prodding me to have a look! :-)
sunfishcode submitted PR Review.
sunfishcode submitted PR Review.
sunfishcode created PR Review Comment:
And
stderrhere?
sunfishcode created PR Review Comment:
How difficult would it be to split this enum out into three separate structs that all implement the
Handletrait independently? Besides the additional dynamic dispatch inside thereadandwritemethods, I think that'd really illustrate how thisHandletrait works -- every different kind of stream has its own impl. There'd be some duplication in the other methods, but it seems like that could be factored out with helper methods.
sunfishcode created PR Review Comment:
Should this be
stdout?
sunfishcode created PR Review Comment:
This can be written as
Self::In { rights } | Self::Out { rights } | Self::Err { rights } => rights.get(),, and similar inset_rights.
sunfishcode created PR Review Comment:
Stdio won't always be a character device, such as when it's redirected from a file ("grep foo < file.txt") or a pipe ("cat file.txt | grep foo"). We still need to do
fstaton it to determine its type.
sunfishcode created PR Review Comment:
Should
OsHandlehave a name withRawin it, since it wraps aRawFd/RawHandle? MaybeRawOSHandle?
sunfishcode created PR Review Comment:
Can you add a comment here briefly explaining what
OsOtheris?
sunfishcode created PR Review Comment:
Why does this use
OsOtherhere? Looking at the code, that seems to be for things that aren't files.
sunfishcode created PR Review Comment:
If I understand correctly, the main use for
update_fromis for thefdstat_set_flags, which on Windows opens a new handle. If that's the only thing that needs it, could we makeupdate_fromon Unix just panic?And, if we don't need to implement
update_from, canOsHandleon Unix hold a plainRawFdinstead of aCell<RawFd>?
kubkon submitted PR Review.
kubkon created PR Review Comment:
Oh shoot, you're absolutely correct, thanks for spotting it!
kubkon submitted PR Review.
kubkon created PR Review Comment:
Likewise here! Makes me start questioning our test suite. Then again, I'm not sure if there will be an obvious way of verifying stdio handles in the CI.
kubkon edited PR Review Comment.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Right, however, here, I think it's safe to assume that our internal
Stdiotype will always be a character device since it is meant to be a wrapper for Rust's stdio primitives. I envisioned that redirections should be handled by a separate entity in the codebase, namely,OsOtherwhich is something like a catch-all for everything not covered with the specific handle types. Does that make sense? In fact, that's why inctx.rswe mapstd::fs::FiletoOsOtheras currently we only ever permit specifying custom fds/handles for stdio when builing the context.
kubkon edited PR Review Comment.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Ah excellent, thanks!
kubkon submitted PR Review.
kubkon created PR Review Comment:
Oh right, sure thing!
kubkon updated PR #1561 from handle-rights to master:
This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are:OsFile,OsDir,Stdio,
andOsOther. Those primitives are separate structs now, each implementing
a subset ofHandlemethods, rather than all being an enumeration of some
supertype such asOsHandle. To summarise the structs:
OsFilerepresents a regular file, and implements fd-ops
ofHandletrait
OsDirrepresents a directory, and primarily implements path-ops, plus
readdirand some common fd-ops such asfdstat, etc.
Stdiorepresents a stdio handle, and implements a subset of fd-ops
such asfdstat_and_read_andwrite_vectoredcalls
OsOthercurrently represents anything else and implements a set similar
to that implemented byStdioThis commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.Some more minor changes include making
OsHandlerepresent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, sinceOsDir
is tricky across OSes, we also have a supertype ofOsHandlecalled
OsDirHandlewhich may store aDIR*stream pointer (mainly BSD). Last but not
least, theFiletypeandRightsare now computed when the resource is created,
rather than every time we callHandle::get_file_typeandHandle::get_rights.
Finally, in order to facilitate the latter, I've convertedEntryRightsinto
HandleRightsand pushed them into eachHandleimplementor.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Hmm, I think this should be fine. It will require some additional tweaks to
WasiCtxBuilderbut nothing major I think.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Makes sense!
kubkon submitted PR Review.
kubkon created PR Review Comment:
Oh, see my reply to your comment about
Stdio:-)
kubkon updated PR #1561 from handle-rights to master:
This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are:OsFile,OsDir,Stdio,
andOsOther. Those primitives are separate structs now, each implementing
a subset ofHandlemethods, rather than all being an enumeration of some
supertype such asOsHandle. To summarise the structs:
OsFilerepresents a regular file, and implements fd-ops
ofHandletrait
OsDirrepresents a directory, and primarily implements path-ops, plus
readdirand some common fd-ops such asfdstat, etc.
Stdiorepresents a stdio handle, and implements a subset of fd-ops
such asfdstat_and_read_andwrite_vectoredcalls
OsOthercurrently represents anything else and implements a set similar
to that implemented byStdioThis commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.Some more minor changes include making
OsHandlerepresent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, sinceOsDir
is tricky across OSes, we also have a supertype ofOsHandlecalled
OsDirHandlewhich may store aDIR*stream pointer (mainly BSD). Last but not
least, theFiletypeandRightsare now computed when the resource is created,
rather than every time we callHandle::get_file_typeandHandle::get_rights.
Finally, in order to facilitate the latter, I've convertedEntryRightsinto
HandleRightsand pushed them into eachHandleimplementor.
kubkon submitted PR Review.
kubkon created PR Review Comment:
OK, I've separated it out into 3 standalone structs:
Stdin,StdoutandStderr.
kubkon edited PR Review Comment.
kubkon submitted PR Review.
kubkon created PR Review Comment:
In order to clear it up a little bit, I've renamed
PendingEntry::FiletoPendingEntry::OsHandle. This naming was somewhat confusing since theFilein this case represented for instance a pipe which we then used in place of a stdio handle. Oh and this is precisely why we useOsOtherhere instead of anOsFile, since the former is meant to represent pipes as well, whereas the latter only regular files.
kubkon updated PR #1561 from handle-rights to master:
This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are:OsFile,OsDir,Stdio,
andOsOther. Those primitives are separate structs now, each implementing
a subset ofHandlemethods, rather than all being an enumeration of some
supertype such asOsHandle. To summarise the structs:
OsFilerepresents a regular file, and implements fd-ops
ofHandletrait
OsDirrepresents a directory, and primarily implements path-ops, plus
readdirand some common fd-ops such asfdstat, etc.
Stdiorepresents a stdio handle, and implements a subset of fd-ops
such asfdstat_and_read_andwrite_vectoredcalls
OsOthercurrently represents anything else and implements a set similar
to that implemented byStdioThis commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.Some more minor changes include making
OsHandlerepresent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, sinceOsDir
is tricky across OSes, we also have a supertype ofOsHandlecalled
OsDirHandlewhich may store aDIR*stream pointer (mainly BSD). Last but not
least, theFiletypeandRightsare now computed when the resource is created,
rather than every time we callHandle::get_file_typeandHandle::get_rights.
Finally, in order to facilitate the latter, I've convertedEntryRightsinto
HandleRightsand pushed them into eachHandleimplementor.
kubkon submitted PR Review.
kubkon created PR Review Comment:
OK, it's done now. Since, as you rightly pointed out in one of the comments above, we don't really need interior mutability on *nix wrt the inner
RawFdinstance, I've also replacedRawFdwithFileinstance which takes care of a couple of ownership related things for us. I believe this is what @iximeow was suggesting all along as well. Now that @sunfishcode pointed out that issuingRawOsHandle::update_fromcall on *nix is a bug, usingFilewas now possible.
kubkon updated PR #1561 from handle-rights to master:
This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are:OsFile,OsDir,Stdio,
andOsOther. Those primitives are separate structs now, each implementing
a subset ofHandlemethods, rather than all being an enumeration of some
supertype such asOsHandle. To summarise the structs:
OsFilerepresents a regular file, and implements fd-ops
ofHandletrait
OsDirrepresents a directory, and primarily implements path-ops, plus
readdirand some common fd-ops such asfdstat, etc.
Stdiorepresents a stdio handle, and implements a subset of fd-ops
such asfdstat_and_read_andwrite_vectoredcalls
OsOthercurrently represents anything else and implements a set similar
to that implemented byStdioThis commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.Some more minor changes include making
OsHandlerepresent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, sinceOsDir
is tricky across OSes, we also have a supertype ofOsHandlecalled
OsDirHandlewhich may store aDIR*stream pointer (mainly BSD). Last but not
least, theFiletypeandRightsare now computed when the resource is created,
rather than every time we callHandle::get_file_typeandHandle::get_rights.
Finally, in order to facilitate the latter, I've convertedEntryRightsinto
HandleRightsand pushed them into eachHandleimplementor.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Done!
kubkon requested alexcrichton, peterhuene and sunfishcode for a review on PR #1561.
sunfishcode submitted PR Review.
sunfishcode created PR Review Comment:
The logic for flushing Rust's stdout buffer is in the
Stdoutimplementation here, and we need that for files too. I expect we're always going to want to useStdoutfor stdout, even when it's attached to a file, in order to ensure that we always stay in sync with Rust's stdout.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Hmm, I'm a little bit confused here. We cannot create a
std::io::Stdoutinstance from a raw file descriptor, so I'm not sure we can ever enforce that we always usesys::stdio::Stdoutfor stdout. I think we could probably think of extractingPipedStdoutor something fromOsOtherthat would haveRawFd/RawHandleattached to it.
kubkon edited PR Review Comment.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Oh, wait, I think I get it now. If the OS redirects the stdio handles, Rust's
Stdoutwill use the redirectedRawFdunderneath, and this one doesn't necessarily have to be a character device. Is that what you meant?
kubkon edited PR Review Comment.
kubkon updated PR #1561 from handle-rights to master:
This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are:OsFile,OsDir,Stdio,
andOsOther. Those primitives are separate structs now, each implementing
a subset ofHandlemethods, rather than all being an enumeration of some
supertype such asOsHandle. To summarise the structs:
OsFilerepresents a regular file, and implements fd-ops
ofHandletrait
OsDirrepresents a directory, and primarily implements path-ops, plus
readdirand some common fd-ops such asfdstat, etc.
Stdiorepresents a stdio handle, and implements a subset of fd-ops
such asfdstat_and_read_andwrite_vectoredcalls
OsOthercurrently represents anything else and implements a set similar
to that implemented byStdioThis commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.Some more minor changes include making
OsHandlerepresent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, sinceOsDir
is tricky across OSes, we also have a supertype ofOsHandlecalled
OsDirHandlewhich may store aDIR*stream pointer (mainly BSD). Last but not
least, theFiletypeandRightsare now computed when the resource is created,
rather than every time we callHandle::get_file_typeandHandle::get_rights.
Finally, in order to facilitate the latter, I've convertedEntryRightsinto
HandleRightsand pushed them into eachHandleimplementor.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Fixed in 0945267. @sunfishcode if you could have a look and lemme know if that's what you had in mind!
sunfishcode submitted PR Review.
sunfishcode created PR Review Comment:
Yes, that's right.
kubkon updated PR #1561 from handle-rights to master:
This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are:OsFile,OsDir,Stdio,
andOsOther. Those primitives are separate structs now, each implementing
a subset ofHandlemethods, rather than all being an enumeration of some
supertype such asOsHandle. To summarise the structs:
OsFilerepresents a regular file, and implements fd-ops
ofHandletrait
OsDirrepresents a directory, and primarily implements path-ops, plus
readdirand some common fd-ops such asfdstat, etc.
Stdiorepresents a stdio handle, and implements a subset of fd-ops
such asfdstat_and_read_andwrite_vectoredcalls
OsOthercurrently represents anything else and implements a set similar
to that implemented byStdioThis commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.Some more minor changes include making
OsHandlerepresent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, sinceOsDir
is tricky across OSes, we also have a supertype ofOsHandlecalled
OsDirHandlewhich may store aDIR*stream pointer (mainly BSD). Last but not
least, theFiletypeandRightsare now computed when the resource is created,
rather than every time we callHandle::get_file_typeandHandle::get_rights.
Finally, in order to facilitate the latter, I've convertedEntryRightsinto
HandleRightsand pushed them into eachHandleimplementor.
sunfishcode submitted PR Review.
sunfishcode submitted PR Review.
sunfishcode created PR Review Comment:
This
expectcould fail if the user passes in the wrong kind of handle? That feels like something where should return aResultand forward the error on, rather than panicking.
sunfishcode created PR Review Comment:
Can you comment on why this
as_filemethod isn't part of theHandletrait? Looking at the implementation below, it's doing a lot ofas_any().downcast_ref<Stuff>(), which seems like it would be avoided if you could just callas_fileon aHandledirectly.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Ah, right! I was meant to do this and somehow forgot. Thanks for pointing this one out!
kubkon submitted PR Review.
kubkon created PR Review Comment:
Hmm, that's an interesting suggestion. So previously,
AsFilewasn't part ofHandletrait since it wasn't fallible, and hence, it wouldn't make much sense forVirtualFile, etc. But now, given that we returnResultI guess we could in principle returnErrno::Badfwhen called by a virtual handle? Or should be outright panic in such a case?
sunfishcode created PR Review Comment:
Oh, right. I wasn't thinking about cases like
VirtualHandle. I think it's fine as is then.
sunfishcode submitted PR Review.
kubkon updated PR #1561 from handle-rights to master:
This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are:OsFile,OsDir,Stdio,
andOsOther. Those primitives are separate structs now, each implementing
a subset ofHandlemethods, rather than all being an enumeration of some
supertype such asOsHandle. To summarise the structs:
OsFilerepresents a regular file, and implements fd-ops
ofHandletrait
OsDirrepresents a directory, and primarily implements path-ops, plus
readdirand some common fd-ops such asfdstat, etc.
Stdiorepresents a stdio handle, and implements a subset of fd-ops
such asfdstat_and_read_andwrite_vectoredcalls
OsOthercurrently represents anything else and implements a set similar
to that implemented byStdioThis commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.Some more minor changes include making
OsHandlerepresent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, sinceOsDir
is tricky across OSes, we also have a supertype ofOsHandlecalled
OsDirHandlewhich may store aDIR*stream pointer (mainly BSD). Last but not
least, theFiletypeandRightsare now computed when the resource is created,
rather than every time we callHandle::get_file_typeandHandle::get_rights.
Finally, in order to facilitate the latter, I've convertedEntryRightsinto
HandleRightsand pushed them into eachHandleimplementor.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Fixed in 36f07cf. So in order not to force public API changes, instead of throwing an error directly at the preopen callsite (either
preopened_dirorpreopened_virt), the creation of the actual instance is now postponed until we build the context object, much like creation of the stdio handles.
kubkon edited PR Review Comment.
sunfishcode submitted PR Review.
sunfishcode merged PR #1561.
Last updated: Dec 06 2025 at 06:05 UTC