Skip to content

openat2 extensibility #1186

@cyphar

Description

@cyphar

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    semver bumpIssues that will require a semver-incompatible fix

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions