-
Notifications
You must be signed in to change notification settings - Fork 248
Description
The kernel API for openat2 is designed to be extensible but the API binding provided by rustix is done in a way that would result in API breakage if a new field was added to openat2 in the future. Ideally, the API would look something more like (idk if AsRef<Openat2How> or Into<Openat2How> is more preferable):
#[non_exhaustive]
#[derive(Clone, Debug, Default)]
pub struct Openat2How {
// NOTE: This is actually a u64 but OFlags is i32. There have been
// discussions about making openat2-only flags before so maybe this should
// be O2Flags or something.
pub flags: OFlags,
pub mode: Mode,
pub resolve: ResolveFlags,
}
pub fn openat2<Fd: AsFd, P: Arg>(dirfd: Fd, path: P, how: &Openat2How) -> Result<OwnedFd>Sadly, the most ergonomic way of instantiating Openat2How wouldn't work:
let how = Openat2How {
flags: ...,
resolve: ...,
..Default::default()
};because #[non_exhaustive] blocks that too. But they could at least do:
let mut how = Openat2How::default();
how.flags = ...;
how.resolve = ...;And then rustix would use std::mem::size_of::<Openat2How>() as the size argument to the syscall. This would allow for future extensions to be added to Openat2How transparently without causing breakages for Rust users -- allowing us to provide the same backward-compatibility that C users of openat2 get.
Because of this limitation, I can't switch my last syscall wrapper in libpathrs from raw libc calls to rustix because I sometimes test extensions in my Rust code and the current API doesn't let you express extensions.
Since changing this would be a breakage and would require a new minor bump for rustix, I'm opening an issue before sending a PR for this. If this API would a bit too ugly to use for most people, then maybe we could make it openat2_raw or something?