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 onlibc
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 fromErrorNumber
to built-in integer types, and also tostd::io::Error
. - Construction functions returning
Option<ErrorNumber>
, for construction from (1) unsigned where 0 is OK and (2) signed result codes from functions likewrite(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());
}
}
}