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_intconst. - Binaries that interact with the kernel directly (e.g. via
asm!()syscalls) need to interpret error numbers, and should not require a dependency onlibcto do so.
I propose adding an ErrorNumber struct to std::os::unix, which would provide limited conversion and comparison capabilities:
-
Eqwould be defined for built-in integer types (i32,u64, etc) -
Fromwould be defined to convert fromErrorNumberto 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());
}
}
}