kubkon opened PR #1443 from yacc to master:
OK, so this PR is a bit of an experiment that came about somewhat itself
when I was looking at refactoring use ofRc<RefCell<Descriptor>>inside
Entrystruct. I've noticed that since we've placedVirtualFileon the
same level asOsHandleandStdinetc., we've ended up necessiitating
checks for different combinations such as "is a real OS resource being mixed
up with a virtual resource?", and if that was the case, we'd panic since
this was clearly not allowed (e.g., symlinking, or worse renaming).
Therefore, it seemed natural for virtual file to be on the same level
as _any_ OS handle (regardless of whether it's an actual file, socket,
or stdio handle). In other words, we should ideally envision the following
hierarchy:\-- OsHandle \-- OsFile -- Stdio \-- VirtualThis way, we can deal with the mix up at a level above which cleans up
our logic significantly.On the other hand, when looking through the
virtfs, the trait approach
to some type that's a validHandlegrew on me, and I think this
is the way to go. And this is what this PR is proposing, a trait
Handlewhich features enough functionality to make both virtual and
OS ops to work. Now, insideEntrywe can safely store something like
Rc<dyn Handle>whereHandlecan downcast to eitherVirtualFileor
VirtualDir, orOsHandleif its an actual OS resource. Note that
I've leftHandleas one massive trait, but I reckon we could split
it up into several smaller traits, each dealing with some bit of WASI
functionality. I'm hoping this would perhaps make it easier to figure
out polyfilling between snapshots and the new upcoming ephemeral
snapshot since a lot of boilerplate functionality is now done as part
of theHandletrait implementation.Next, I've redone the original
OsHandleto be anOsFilewhich
now stores a raw descriptor/handle (RawFd/RawHandle) inside a
Cellso that we can handle interior mutability in an easy (read,
non-panicky) way. In order not to lose the perks of derefercing to
std::fs::File, I've added a convenience traitAsFilewhich
will takeOsFileby reference (or the stdio handles) and create
a non-ownedManuallyDrop<File>resource which can be passed around
and acted upon the way we'd normally do on&File. This change of
course implies that we now have to worry about properly closing all
OS resources stored as part ofOsFile, thus this type now implements
Droptrait which essentially speaking moves the raw descriptor/handle
into aFileand drops it.Finally, I've redone setting time info on relative paths on *nix using
the same approach as advocated in the virtual fs. Namely, we do an
openatfollowed byfilestat_set_timeson the obtained descriptor.
This effectively removes the need for customfiletimemodule in
yanix. However, this does probably incur additional cost of at least
one additional syscall, and I haven't checked whether this approach
performs as expected on platforms such as NixOS which as far as I remember
had some weirdness todo with linkingutimensatsymbols, etc. Still,
this change is worth considering given that the implementation of
path_filestat_set_timescleans up a lot, albeit with some additional
cost.Anyhow, lemme y'all know what you think!
PS, if anybody is wondering why the incoming branch is called
yacc,
it stands for "yet another cleanup cleanup" simply because I was out
of ideas...
kubkon requested iximeow for a review on PR #1443.
kubkon requested sunfishcode and iximeow for a review on PR #1443.
kubkon assigned PR #1443 to alexcrichton.
kubkon unassigned PR #1443 to alexcrichton.
kubkon requested alexcrichton, sunfishcode and iximeow for a review on PR #1443.
kubkon updated PR #1443 from yacc to master:
OK, so this PR is a bit of an experiment that came about somewhat itself
when I was looking at refactoring use ofRc<RefCell<Descriptor>>inside
Entrystruct. I've noticed that since we've placedVirtualFileon the
same level asOsHandleandStdinetc., we've ended up necessiitating
checks for different combinations such as "is a real OS resource being mixed
up with a virtual resource?", and if that was the case, we'd panic since
this was clearly not allowed (e.g., symlinking, or worse renaming).
Therefore, it seemed natural for virtual file to be on the same level
as _any_ OS handle (regardless of whether it's an actual file, socket,
or stdio handle). In other words, we should ideally envision the following
hierarchy:\-- OsHandle \-- OsFile -- Stdio \-- VirtualThis way, we can deal with the mix up at a level above which cleans up
our logic significantly.On the other hand, when looking through the
virtfs, the trait approach
to some type that's a validHandlegrew on me, and I think this
is the way to go. And this is what this PR is proposing, a trait
Handlewhich features enough functionality to make both virtual and
OS ops to work. Now, insideEntrywe can safely store something like
Rc<dyn Handle>whereHandlecan downcast to eitherVirtualFileor
VirtualDir, orOsHandleif its an actual OS resource. Note that
I've leftHandleas one massive trait, but I reckon we could split
it up into several smaller traits, each dealing with some bit of WASI
functionality. I'm hoping this would perhaps make it easier to figure
out polyfilling between snapshots and the new upcoming ephemeral
snapshot since a lot of boilerplate functionality is now done as part
of theHandletrait implementation.Next, I've redone the original
OsHandleto be anOsFilewhich
now stores a raw descriptor/handle (RawFd/RawHandle) inside a
Cellso that we can handle interior mutability in an easy (read,
non-panicky) way. In order not to lose the perks of derefercing to
std::fs::File, I've added a convenience traitAsFilewhich
will takeOsFileby reference (or the stdio handles) and create
a non-ownedManuallyDrop<File>resource which can be passed around
and acted upon the way we'd normally do on&File. This change of
course implies that we now have to worry about properly closing all
OS resources stored as part ofOsFile, thus this type now implements
Droptrait which essentially speaking moves the raw descriptor/handle
into aFileand drops it.Finally, I've redone setting time info on relative paths on *nix using
the same approach as advocated in the virtual fs. Namely, we do an
openatfollowed byfilestat_set_timeson the obtained descriptor.
This effectively removes the need for customfiletimemodule in
yanix. However, this does probably incur additional cost of at least
one additional syscall, and I haven't checked whether this approach
performs as expected on platforms such as NixOS which as far as I remember
had some weirdness todo with linkingutimensatsymbols, etc. Still,
this change is worth considering given that the implementation of
path_filestat_set_timescleans up a lot, albeit with some additional
cost.Anyhow, lemme y'all know what you think!
PS, if anybody is wondering why the incoming branch is called
yacc,
it stands for "yet another cleanup cleanup" simply because I was out
of ideas...
kubkon updated PR #1443 from yacc to master:
OK, so this PR is a bit of an experiment that came about somewhat itself
when I was looking at refactoring use ofRc<RefCell<Descriptor>>inside
Entrystruct. I've noticed that since we've placedVirtualFileon the
same level asOsHandleandStdinetc., we've ended up necessiitating
checks for different combinations such as "is a real OS resource being mixed
up with a virtual resource?", and if that was the case, we'd panic since
this was clearly not allowed (e.g., symlinking, or worse renaming).
Therefore, it seemed natural for virtual file to be on the same level
as _any_ OS handle (regardless of whether it's an actual file, socket,
or stdio handle). In other words, we should ideally envision the following
hierarchy:\-- OsHandle \-- OsFile -- Stdio \-- VirtualThis way, we can deal with the mix up at a level above which cleans up
our logic significantly.On the other hand, when looking through the
virtfs, the trait approach
to some type that's a validHandlegrew on me, and I think this
is the way to go. And this is what this PR is proposing, a trait
Handlewhich features enough functionality to make both virtual and
OS ops to work. Now, insideEntrywe can safely store something like
Rc<dyn Handle>whereHandlecan downcast to eitherVirtualFileor
VirtualDir, orOsHandleif its an actual OS resource. Note that
I've leftHandleas one massive trait, but I reckon we could split
it up into several smaller traits, each dealing with some bit of WASI
functionality. I'm hoping this would perhaps make it easier to figure
out polyfilling between snapshots and the new upcoming ephemeral
snapshot since a lot of boilerplate functionality is now done as part
of theHandletrait implementation.Next, I've redone the original
OsHandleto be anOsFilewhich
now stores a raw descriptor/handle (RawFd/RawHandle) inside a
Cellso that we can handle interior mutability in an easy (read,
non-panicky) way. In order not to lose the perks of derefercing to
std::fs::File, I've added a convenience traitAsFilewhich
will takeOsFileby reference (or the stdio handles) and create
a non-ownedManuallyDrop<File>resource which can be passed around
and acted upon the way we'd normally do on&File. This change of
course implies that we now have to worry about properly closing all
OS resources stored as part ofOsFile, thus this type now implements
Droptrait which essentially speaking moves the raw descriptor/handle
into aFileand drops it.Finally, I've redone setting time info on relative paths on *nix using
the same approach as advocated in the virtual fs. Namely, we do an
openatfollowed byfilestat_set_timeson the obtained descriptor.
This effectively removes the need for customfiletimemodule in
yanix. However, this does probably incur additional cost of at least
one additional syscall, and I haven't checked whether this approach
performs as expected on platforms such as NixOS which as far as I remember
had some weirdness todo with linkingutimensatsymbols, etc. Still,
this change is worth considering given that the implementation of
path_filestat_set_timescleans up a lot, albeit with some additional
cost.Anyhow, lemme y'all know what you think!
PS, if anybody is wondering why the incoming branch is called
yacc,
it stands for "yet another cleanup cleanup" simply because I was out
of ideas...
pchickey submitted PR Review.
pchickey submitted PR Review.
pchickey created PR Review Comment:
left in some commented out debugs here and just below
alexcrichton submitted PR Review.
kubkon updated PR #1443 from yacc to master:
OK, so this PR is a bit of an experiment that came about somewhat itself
when I was looking at refactoring use ofRc<RefCell<Descriptor>>inside
Entrystruct. I've noticed that since we've placedVirtualFileon the
same level asOsHandleandStdinetc., we've ended up necessiitating
checks for different combinations such as "is a real OS resource being mixed
up with a virtual resource?", and if that was the case, we'd panic since
this was clearly not allowed (e.g., symlinking, or worse renaming).
Therefore, it seemed natural for virtual file to be on the same level
as _any_ OS handle (regardless of whether it's an actual file, socket,
or stdio handle). In other words, we should ideally envision the following
hierarchy:\-- OsHandle \-- OsFile -- Stdio \-- VirtualThis way, we can deal with the mix up at a level above which cleans up
our logic significantly.On the other hand, when looking through the
virtfs, the trait approach
to some type that's a validHandlegrew on me, and I think this
is the way to go. And this is what this PR is proposing, a trait
Handlewhich features enough functionality to make both virtual and
OS ops to work. Now, insideEntrywe can safely store something like
Rc<dyn Handle>whereHandlecan downcast to eitherVirtualFileor
VirtualDir, orOsHandleif its an actual OS resource. Note that
I've leftHandleas one massive trait, but I reckon we could split
it up into several smaller traits, each dealing with some bit of WASI
functionality. I'm hoping this would perhaps make it easier to figure
out polyfilling between snapshots and the new upcoming ephemeral
snapshot since a lot of boilerplate functionality is now done as part
of theHandletrait implementation.Next, I've redone the original
OsHandleto be anOsFilewhich
now stores a raw descriptor/handle (RawFd/RawHandle) inside a
Cellso that we can handle interior mutability in an easy (read,
non-panicky) way. In order not to lose the perks of derefercing to
std::fs::File, I've added a convenience traitAsFilewhich
will takeOsFileby reference (or the stdio handles) and create
a non-ownedManuallyDrop<File>resource which can be passed around
and acted upon the way we'd normally do on&File. This change of
course implies that we now have to worry about properly closing all
OS resources stored as part ofOsFile, thus this type now implements
Droptrait which essentially speaking moves the raw descriptor/handle
into aFileand drops it.Finally, I've redone setting time info on relative paths on *nix using
the same approach as advocated in the virtual fs. Namely, we do an
openatfollowed byfilestat_set_timeson the obtained descriptor.
This effectively removes the need for customfiletimemodule in
yanix. However, this does probably incur additional cost of at least
one additional syscall, and I haven't checked whether this approach
performs as expected on platforms such as NixOS which as far as I remember
had some weirdness todo with linkingutimensatsymbols, etc. Still,
this change is worth considering given that the implementation of
path_filestat_set_timescleans up a lot, albeit with some additional
cost.Anyhow, lemme y'all know what you think!
PS, if anybody is wondering why the incoming branch is called
yacc,
it stands for "yet another cleanup cleanup" simply because I was out
of ideas...
iximeow submitted PR Review.
iximeow submitted PR Review.
iximeow created PR Review Comment:
Why the
+ 'statichere? My understanding of the interaction between lifetimes/trait objects is kind of fuzzy, but isn't'staticthe implied default? (I'm not sure why we'd want to forbid non-'static, either)
iximeow created PR Review Comment:
What _is_ the
TODOhere? Theget_file_type() == Errcase?
iximeow created PR Review Comment:
update_fromon anOsFilethat has adirwithSomewould then have a staledir. I'm not sure how much an issue this actually is, since we onlyupdate_frominfdstat_set_flags. Flags are on the referenced filesystem entry, not on thefd, right? So inconsistent flags aren't actually possible? Otherwise we might end up in a state wheredirwas populated can iterate when it shouldn't, or can't iterate when it should.At the very least, if this is sound (and I suspect it is), I think it'd be good to have a comment describing why alongside this impl.
iximeow created PR Review Comment:
ReOpenFilerequires the file handle came fromCreateFile, but the standard library will useGetStdHandlerather thanCreateFile("CONIN$",...orCONOUT$. If it works I'd be a little suspect of it mysteriously breaking one day. Judging by https://github.com/rust-lang/rust/issues/40490 (found when looking to confirm how stdlib deals with Windows stdio) it seems pretty suspect to retain a stdio handle in the first place?Nothing specific to add, just topical thought meandering, sorry :sweat_smile:
pchickey submitted PR Review.
pchickey created PR Review Comment:
That syntax threw me off when I learned it a week or two ago, it just means that the
Handleconcrete type cant have a lifetime.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Yep, exactly as @pchickey said. I can't foresee a situation where type that implements
Handlewouldn't last for the entire duration of the program.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Oh right, I forgot to remove it. Thanks for spotting this one!
kubkon created PR Review Comment:
That's an excellent observation, thanks! I think adding a comment to remember about this potential issue is the best thing to do here.
On a related albeit somewhat different note, I'd still like to refactor how we store the
DIRstream pointer on BSDes inOsFile. Having an embeddedOptionseems like a less than ideal solution to use here. I was actually thinking of splitting the type into two or possibly an enum, so that if we are dealing with a dir on BSD, we'd immediately store a validDIRstream pointer. But this will be a subsequent PR :-)
kubkon submitted PR Review.
kubkon submitted PR Review.
kubkon created PR Review Comment:
Oh good find, thanks! So if I understood it right, modifying stdio should error out on Windows since the handle was obtained from
GetStdHandleand notCreateFile. I'm keen to leave some sort of TODO here anyway to investigate this further on Windows.
kubkon updated PR #1443 from yacc to master:
OK, so this PR is a bit of an experiment that came about somewhat itself
when I was looking at refactoring use ofRc<RefCell<Descriptor>>inside
Entrystruct. I've noticed that since we've placedVirtualFileon the
same level asOsHandleandStdinetc., we've ended up necessiitating
checks for different combinations such as "is a real OS resource being mixed
up with a virtual resource?", and if that was the case, we'd panic since
this was clearly not allowed (e.g., symlinking, or worse renaming).
Therefore, it seemed natural for virtual file to be on the same level
as _any_ OS handle (regardless of whether it's an actual file, socket,
or stdio handle). In other words, we should ideally envision the following
hierarchy:\-- OsHandle \-- OsFile -- Stdio \-- VirtualThis way, we can deal with the mix up at a level above which cleans up
our logic significantly.On the other hand, when looking through the
virtfs, the trait approach
to some type that's a validHandlegrew on me, and I think this
is the way to go. And this is what this PR is proposing, a trait
Handlewhich features enough functionality to make both virtual and
OS ops to work. Now, insideEntrywe can safely store something like
Rc<dyn Handle>whereHandlecan downcast to eitherVirtualFileor
VirtualDir, orOsHandleif its an actual OS resource. Note that
I've leftHandleas one massive trait, but I reckon we could split
it up into several smaller traits, each dealing with some bit of WASI
functionality. I'm hoping this would perhaps make it easier to figure
out polyfilling between snapshots and the new upcoming ephemeral
snapshot since a lot of boilerplate functionality is now done as part
of theHandletrait implementation.Next, I've redone the original
OsHandleto be anOsFilewhich
now stores a raw descriptor/handle (RawFd/RawHandle) inside a
Cellso that we can handle interior mutability in an easy (read,
non-panicky) way. In order not to lose the perks of derefercing to
std::fs::File, I've added a convenience traitAsFilewhich
will takeOsFileby reference (or the stdio handles) and create
a non-ownedManuallyDrop<File>resource which can be passed around
and acted upon the way we'd normally do on&File. This change of
course implies that we now have to worry about properly closing all
OS resources stored as part ofOsFile, thus this type now implements
Droptrait which essentially speaking moves the raw descriptor/handle
into aFileand drops it.Finally, I've redone setting time info on relative paths on *nix using
the same approach as advocated in the virtual fs. Namely, we do an
openatfollowed byfilestat_set_timeson the obtained descriptor.
This effectively removes the need for customfiletimemodule in
yanix. However, this does probably incur additional cost of at least
one additional syscall, and I haven't checked whether this approach
performs as expected on platforms such as NixOS which as far as I remember
had some weirdness todo with linkingutimensatsymbols, etc. Still,
this change is worth considering given that the implementation of
path_filestat_set_timescleans up a lot, albeit with some additional
cost.Anyhow, lemme y'all know what you think!
PS, if anybody is wondering why the incoming branch is called
yacc,
it stands for "yet another cleanup cleanup" simply because I was out
of ideas...
kubkon updated PR #1443 from yacc to master:
OK, so this PR is a bit of an experiment that came about somewhat itself
when I was looking at refactoring use ofRc<RefCell<Descriptor>>inside
Entrystruct. I've noticed that since we've placedVirtualFileon the
same level asOsHandleandStdinetc., we've ended up necessiitating
checks for different combinations such as "is a real OS resource being mixed
up with a virtual resource?", and if that was the case, we'd panic since
this was clearly not allowed (e.g., symlinking, or worse renaming).
Therefore, it seemed natural for virtual file to be on the same level
as _any_ OS handle (regardless of whether it's an actual file, socket,
or stdio handle). In other words, we should ideally envision the following
hierarchy:\-- OsHandle \-- OsFile -- Stdio \-- VirtualThis way, we can deal with the mix up at a level above which cleans up
our logic significantly.On the other hand, when looking through the
virtfs, the trait approach
to some type that's a validHandlegrew on me, and I think this
is the way to go. And this is what this PR is proposing, a trait
Handlewhich features enough functionality to make both virtual and
OS ops to work. Now, insideEntrywe can safely store something like
Rc<dyn Handle>whereHandlecan downcast to eitherVirtualFileor
VirtualDir, orOsHandleif its an actual OS resource. Note that
I've leftHandleas one massive trait, but I reckon we could split
it up into several smaller traits, each dealing with some bit of WASI
functionality. I'm hoping this would perhaps make it easier to figure
out polyfilling between snapshots and the new upcoming ephemeral
snapshot since a lot of boilerplate functionality is now done as part
of theHandletrait implementation.Next, I've redone the original
OsHandleto be anOsFilewhich
now stores a raw descriptor/handle (RawFd/RawHandle) inside a
Cellso that we can handle interior mutability in an easy (read,
non-panicky) way. In order not to lose the perks of derefercing to
std::fs::File, I've added a convenience traitAsFilewhich
will takeOsFileby reference (or the stdio handles) and create
a non-ownedManuallyDrop<File>resource which can be passed around
and acted upon the way we'd normally do on&File. This change of
course implies that we now have to worry about properly closing all
OS resources stored as part ofOsFile, thus this type now implements
Droptrait which essentially speaking moves the raw descriptor/handle
into aFileand drops it.Finally, I've redone setting time info on relative paths on *nix using
the same approach as advocated in the virtual fs. Namely, we do an
openatfollowed byfilestat_set_timeson the obtained descriptor.
This effectively removes the need for customfiletimemodule in
yanix. However, this does probably incur additional cost of at least
one additional syscall, and I haven't checked whether this approach
performs as expected on platforms such as NixOS which as far as I remember
had some weirdness todo with linkingutimensatsymbols, etc. Still,
this change is worth considering given that the implementation of
path_filestat_set_timescleans up a lot, albeit with some additional
cost.Anyhow, lemme y'all know what you think!
PS, if anybody is wondering why the incoming branch is called
yacc,
it stands for "yet another cleanup cleanup" simply because I was out
of ideas...
kubkon merged PR #1443.
Last updated: Dec 13 2025 at 19:03 UTC