Crate precisej_printable_errno[][src]

Expand description

Printable system call errors for nix. CURRENTLY IN DEVELOPMENT

What?

precisej-printable-errno is a simple library that adds the possibility of attaching a printable error message to every Errno. It additionally lets you add an integer error code that can be used to exit the application.

The library is intended to be used by lower-level applications that intend to use nix’s Rust-friendly bindings to libc system functions.

Note: precisej-printable-errno’s authors have no relationship with the nix-rust maintainers.

Where?

Any system that nix supports should be supported by precisej-printable-errno. To use this library, add precisej-printable-errno = "$LIB_VERSION" (replacing $LIB_VERSION with the latest version available in crates.io).

Projects currently using precisej-printable-errno:

  • initd

If you are the author of another Rust project, are using the library, and would like to be mentioned here, please contact me.

Why?

When writing initd, I found that there wasn’t a straightforward way to bubble up an exit code, and resorted to having a main() function call a function which would return an i32, and then call std::process::exit with the resulting error code. This was unergonomic and bypassed Rust’s excellent Result handling. Therefore I decided to create special Error structs containing an error message and an exit code, and since I found it useful I decided to turn it into a library crate.

I didn’t find out how to do anything similar with other libraries such as anyhow. If someone finds a better, equally lightweight alternative please contact me.

Why not Termination?

As of 2021-12-10, std::process::Termination is unstable and requires the termination_trait_lib feature, which can only be activated in nightly versions of Rust. Not all programs can make use of nightly (some, such as initd, deny the use of unstable features in its codebase), for which this crate exists.

Not all of this library’s functionality can be replicated with std::process::Termination, so this library can be of use even for users of nightly Rust, albeit somewhat awkwardly. Future versions of precisej-printable-errno will optionally include an implementation of std::process::Termination for ExitError as a non-default feature for interested nightly users.

How?

/* use ... */

const PROGRAM_NAME: &'static str = "example-program";

pub fn main() {
    if let Err(e) = start() {
        e.eprint_and_exit()
    }
}

pub fn start() -> Result<(), ExitError<String>> {
    let init_file = open("/sbin/init", OFlag::O_RDONLY, Mode::empty())
        .printable(PROGRAM_NAME, "unable to open /sbin/init")
        .bail(1)?;

    let mut buf = [0; 1024];
    read(init_file, &mut buf)
        .printable(PROGRAM_NAME, "unable to read first KB of /sbin/init")
        .bail(2)?;

    drop(buf);

    open("/path/to/nonexistent/file", OFlag::O_RDONLY, Mode::empty())
        .printable(PROGRAM_NAME, format!("unable to open {}", "/path/to/nonexistent/file"))
        .bail(3)?;

    // That last call should have caused the process to exit with
    // code 3 and the following error message:
    //
    // example-program: unable to open /path/to/nonexistent/file: No such file or directory

    Ok(())
}

Structs

This struct contains an exit code and basic error information (from PrintableErrno). Unless you unwrap the error on a Result containing an ExitError, you probably won’t use this directly.

This is the base struct containing basic error information. Unless you call printable_error or you unwrap the error on a Result containing a PrintableErrno, you probably won’t use this directly.

Traits

This trait defines a Result with a nix Errno, facilitating the conversion of the error to PrintableErrno.

This trait defines a Result with our own ExitError. This allows exiting the program with the error code specified by the ExitError, as well as consuming itself and returning an Option after printing the Error to stderr.

This trait defines a Result with our own PrintableErrno, allowing further conversion to ExitError, or printing and returning and Option.

Functions

Creates an error out of the program name and the supplied message. Useful when an Errno isn’t present, but the program wants to signal a problem to the user and possibly exit if it’s fatal.