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}