Skip to content

fs::openat2 is unavailable when building with --cfg=rustix_no_linux_raw (e.g., in AOSP) - #1713

Open
tylersaunders wants to merge 1 commit into
bytecodealliance:mainfrom
tylersaunders:openat2-android
Open

tylersaunders wants to merge 1 commit into
bytecodealliance:mainfrom
tylersaunders:openat2-android

Conversation

@tylersaunders

Copy link
Copy Markdown

Hello, while moving some cpp code over to rust inside of AOSP, I encounted openat2 not being useable on android linux due to some configuration, and a minor issue with the open_how struct not being available outside of linux_raw_sys

rustix::fs::openat2 is currently gated on #[cfg(linux_raw_dep)] in src/fs/mod.rs, src/backend/libc/fs/syscalls.rs, and tests/fs/main.rs, making it unavailable on Linux and Android when building with --cfg=rustix_no_linux_raw (such as in AOSP, which builds rustix with the libc backend and without linux-raw-sys).

Background Context

In #1478 (fda7cbe6), --cfg=rustix_no_linux_raw was introduced so projects like AOSP and Mesa3D can build rustix on Linux and Android using the libc backend without depending on linux-raw-sys.

In that change, openat2 was switched from #[cfg(linux_kernel)] to #[cfg(linux_raw_dep)] in:

  • src/fs/mod.rs (mod openat2; and pub use openat2::openat2;)
  • src/backend/libc/fs/syscalls.rs (pub(crate) fn openat2)

However, all other openat2 support in the libc backend is already independent of linux-raw-sys and gated on #[cfg(linux_kernel)]:

  • rustix::fs::ResolveFlags in src/backend/libc/fs/types.rs is gated on #[cfg(linux_kernel)] (and its rustdoc links to [openat2]: crate::fs::openat2, which is broken when not(linux_raw_dep)).
  • use crate::fs::ResolveFlags and const SYS_OPENAT2 = 437 in src/backend/libc/fs/syscalls.rs are already gated on #[cfg(linux_kernel)].

The only dependency on linux-raw-sys inside src/backend/libc/fs/syscalls.rs::openat2 is use linux_raw_sys::general::open_how; for the 24-byte kernel ABI struct (struct open_how { flags: u64, mode: u64, resolve: u64 }). Note that libc::open_how cannot be used directly because it is not defined for target_os = "android" in libc and is marked #[non_exhaustive] on target_os = "linux".

Proposed Solution (see attached commit)

  1. In src/backend/libc/fs/syscalls.rs::openat2, define #[repr(C)] struct open_how { flags: u64, mode: u64, resolve: u64 } when #[cfg(not(linux_raw_dep))] (retaining use linux_raw_sys::general::open_how; when #[cfg(linux_raw_dep)]).
  2. Change the cfg gate on openat2 in src/fs/mod.rs, src/backend/libc/fs/syscalls.rs, and tests/fs/main.rs from #[cfg(linux_raw_dep)] back to #[cfg(linux_kernel)].

I've tested & verified the behavior of this patch in one of our cpp -> rust migrations inside of AOSP. Ideally I'd like to land this upstream rather than maintaining our own AOSP patch downstream.

`rustix::fs::openat2` and its libc backend implementation were gated on
`#[cfg(linux_raw_dep)]` in commit fda7cbe ("rustix: on Linux, support
a build without linux-raw-sys (bytecodealliance#1478)") because
`backend::fs::syscalls::openat2` imported
`linux_raw_sys::general::open_how`. Meanwhile, the supporting
`ResolveFlags` bitflags and `SYS_OPENAT2` constant in the libc backend
remained gated on `#[cfg(linux_kernel)]`.

Because `libc::open_how` is not defined for `target_os = "android"` and
is marked `#[non_exhaustive]` on `target_os = "linux"`, define
`#[repr(C)] struct open_how` locally in `backend::fs::syscalls::openat2`
when `#[cfg(not(linux_raw_dep))]` and gate `openat2` on
`#[cfg(linux_kernel)]`. This makes `rustix::fs::openat2` usable on
Android and Linux when building with `--cfg=rustix_no_linux_raw`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant