Description
The README for the libc
crate says:
libc provides all of the definitions necessary to easily interoperate with C code (or "C-like" code) on each of the platforms that Rust supports. This includes type definitions (e.g. c_int), constants (e.g. EINVAL) as well as function headers (e.g. malloc).
This isn't true; it doesn't provide errno
. There's a large hole in the documentation surrounding this, and it's really unclear to me (as someone who just wants to call some libc
functions) what the correct solution is.
Previous discussion: #47 .
The closest thing to a mention of errno
in the libc
crate is __errno_location
(https://doc.rust-lang.org/1.6.0/libc/fn.__errno_location.html), which has leading underscores and no documentation, suggesting that it's a private API which was exposed accidentally.
The std
crate has std::io::last_os_error
(https://doc.rust-lang.org/std/io/struct.Error.html#method.last_os_error), which is sort-of like errno, but not quite enough like errno to actually match up with anything you'd find in manpage. It has std::io::ErrorKind
(https://doc.rust-lang.org/std/io/enum.ErrorKind.html) which has error types which sound like common errnos, but if they're supposed to be the same, it has failed to document this, and it's not exhaustive. Also it's read-only, which is insufficient for many some libc functions, where the convention is to set errno to 0 before calling them.
There's an errno
crate, which provides both a getter and setter, but it's by a single developer rather than the rust core team, and there's no particular reason to trust its portability or long-term stability.
There used to be a std::os::errno
. It's gone, but ranks #2 in the Google search results for "rust errno" (https://www.reddit.com/r/rust/comments/31b9zw/is_stdoserrno_no_longer_available/). Just to rub it in.
The nix
crate (which depends on libc
and provides lots of wrappers) has nix::errno::errno
and nix::errno::from_i32
, which is what I've settled on for my own use. (Still readonly, and this bothers me from a soundness standpoint, but I can live with it). AFAICT nix
is not by the Rust core team, but at least it's widely used and appears maintained.
Sorting through all this took a bunch of time, when all I really wanted was to call some familiar libc
functions. I see a few possible options here:
- Add
errno
getter and setter functions to thelibc
crate. - Document the mapping between
std::io::last_os_error
results anderrno
, make it exhaustive, and leave a note in theREADME
saying that's where to go for errnos. - Change the messaging in the
README
to make it clear thatlibc
is not self-contained, but requires another crate (such aserrno
ornix
) to use correctly.