program/
lib.rs

1//! Program provides a single divergent function (`perror`) to emulate C's `perror`
2
3#![warn(clippy::pedantic)]
4
5use std::ffi;
6use std::io::{self, Write};
7use std::process;
8
9/// Print an error message to `stderr` and exit with an exit status of `1`.
10///
11/// While this function attempts to obtain and write the  name of the current process to `stderr`,
12/// write `e` to `stderr`, and exit with an exit status of `1`, only exiting is guranteed.
13/// Unfortunately a lot can go wrong when getting the name of the current process.
14/// If  for any reason the name of the current process cannot be formed, just print
15/// the error given by the user. If the error given by the use cannot be written to stderr just
16/// exit with an exit status of 1.
17pub fn perror<E: std::fmt::Display>(e: E) -> ! {
18    if let Some(cmd) = process_name() {
19        let _ = write!(io::stderr(), "{}: ", cmd.to_string_lossy());
20    }
21
22    let _ = writeln!(io::stderr(), "{}", e);
23    process::exit(1)
24}
25
26/// Attempt to obtain the name of the current process.
27///
28/// Return `Some(process_name)` or `None` if it cannot be obtained.
29fn process_name() -> Option<ffi::OsString> {
30    let cmd = std::env::current_exe().ok()?;
31    let process = cmd.file_name()?;
32    Some(process.to_os_string())
33}