rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.32k stars 12.72k forks source link

Make (most?) `std::os::wasi::fs::FileExt` functions available on all Unix platforms #102776

Open alyssais opened 2 years ago

alyssais commented 2 years ago

The methods in std::os::wasi::fs::FileExt look a lot like the POSIX *at methods. Would it be possible to make this extension available for all Unix platforms, rather than limiting it to wasi?

There are a lot of reasons to want to use these methods from other Unix operating systems:

Tracking issue for wasi_ext: https://github.com/rust-lang/rust/issues/71213

ChrisDenton commented 2 years ago

There is definitely a lot of interest in bringing *at style functions to more that just os::wasi. The ideal would be to have cross-platform APIs where possible rather than something Unix specific.

the8472 commented 2 years ago

I don't think the wasi API is ideal. Usually you need to hold onto a directory and be able to iterate it at the same time. So the *at methods should primarily be available on a ReadDir and optionally on File. If we do this in std then this can be done via a trait or a Fd wrapper type.

But if we want to let other crates handle this, e.g. to support async support then they'd need a way to get access to the file descriptor in ReadDir. But that's problematic due to the posix spec:

Upon successful return from fdopendir(), the file descriptor is under the control of the system, and if any attempt is made to close the file descriptor, or to modify the state of the associated description, other than by means of closedir(), readdir(), readdir_r(), rewinddir(), or seekdir(), the behavior is undefined. Upon calling closedir() the file descriptor shall be closed.

There are ways around this by making the function unsafe, by attempting to reopen the file descriptor (which can fail) or by using getdents-style syscalls on each platform. Each of those approaches has downsides. Or perhaps we could ask the standards body to clarify why this is UB. If it were merely implementation-defined behavior we could shrug and let people get the file descriptor at the risk of getting garbage when using the descriptor for multiple concurrent directory iterations.

Anyway, some design work is needed.

Some prior discussion https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Path.20reform.202022 https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/ReadDir's.20fd