Pre-RFC: POSIX error numbers in `std::os::unix`

The POSIX standard defines a set of named "error numbers", such as EIO or EPIPE, for use in communicating error conditions from low-level OS routines. Many of these are currently exposed in libc as c_int constants, because they figure prominently in writing bindings to libc on UNIX platforms.

However, there are two problems with this solution:

  • POSIX does not specify the type of these error numbers -- they are defined as C macros, which are untyped integer literals. Many traditional UNIX APIs assume that they can use any integer type for returning error numbers, which is awkward to use with a c_int const.
  • Binaries that interact with the kernel directly (e.g. via asm!() syscalls) need to interpret error numbers, and should not require a dependency on libc to do so.

I propose adding an ErrorNumber struct to std::os::unix, which would provide limited conversion and comparison capabilities:

  • Eq would be defined for built-in integer types (i32, u64, etc)
  • From would be defined to convert from ErrorNumber to built-in integer types, and also to std::io::Error.
  • Construction functions returning Option<ErrorNumber>, for construction from (1) unsigned where 0 is OK and (2) signed result codes from functions like write(2).

The OS-specific integer constants would be associated values of ErrorNumber, yielding code like this:

use std::os::unix::ErrorNumber;

fn some_syscall() -> io::Result<()> {
  while {
    let err = some_syscall_raw();
    if err == 0 {
      return Ok(());
    }
    if err != ErrorNumber::EAGAIN {
      return Err(err.into());
    }
  }
}
1 Like

Why not?

In general, std should provide cross-platform abstractions for often-used primitives. I don't think it needs to provide any facilities for directly invoking syscalls with assembly, and I don't think it needs to provide POSIX definitions in general.

3 Likes

We already of unix specific functions in std behind cfg!'s, so I don't see why adding this would be a bad idea

There are a number of people interested in a libc-free target on some *nix platforms. And as Nokel81 mentions, std already exports a number of *nix-only APIs.

rust-lang/rfcs PR: https://github.com/rust-lang/rfcs/pull/2973

1 Like