rust-lang / libc

Raw bindings to platform APIs for Rust
https://docs.rs/libc
Apache License 2.0
2.08k stars 1.04k forks source link

Use `pub safe` from Rust 1.82 in `extern` blocks? #4001

Open mgeisler opened 2 hours ago

mgeisler commented 2 hours ago

Hello! I was reviewing a change to some Rust code in AOSP the other day, and they call libc::listen. This is an unsafe function, so I asked them to document the preconditions in a safety comment above the unsafe block.

Now, I saw that Rust 1.82 has support for safe functions in otherwise unsafe extern blocks. So one can do:

unsafe extern {
    pub safe fn sqrt(x: f64) -> f64;
}

fn main() {
    dbg!(sqrt(123.0));
}

I'm not an expert on this, but looking at listen(2), it occured to me that the function might be safe to call with all inputs: the Kernel will return -1 if the integers passed in are not valid?

This is just a motivating example: could libc begin marking some of its functions as being safe in this way?

This would of course be a conditional thing based on the Rust version used.

mgeisler commented 2 hours ago

This is of course much harder than I imagined 😄 I tried it out by marking abs as safe and this makes cargo test in libc-test fail with:

  --- stderr
  error: expected `fn`, found `{`
      --> ../src/unix/linux_like/linux/mod.rs:5514:15
       |
  5514 | unsafe extern {
       |              -^ unexpected token
       |              |
       |              expected `fn` here

  thread 'main' panicked at .../index.crates.io-6f17d22bba15001f/garando_syntax-0.1.1/src/ext/tt/macro_parser.rs:526:25:
  parser fatal error

So it seems that https://lib.rs/garando_syntax will need to update first.