Skip to content

Documentation gap surrounding errno #1644

Closed
@jimrandomh

Description

@jimrandomh

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 the libc crate.
  • Document the mapping between std::io::last_os_error results and errno, make it exhaustive, and leave a note in the README saying that's where to go for errnos.
  • Change the messaging in the README to make it clear that libc is not self-contained, but requires another crate (such as errno or nix) to use correctly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions