std::io::Error
显示的错误消息带有“(os error n)”后缀,可通过运行以下程序轻松复制:
use std::fs;
use std::io::Write;
fn main() {
let fl = "no such file";
if let Err(e) = fs::metadata(fl) {
writeln!(std::io::stderr(), "{}: {}", fl, e).unwrap();
}
}
输出:
no such file: No such file or directory (os error 2)
如何获得系统提供的系统错误消息,即没有“os error 2”部分?
我试过了:
调用e.description()
,它返回一条不同的错误消息(“未找到实体”),这很有用,但不是我正在寻找的内容;
检查Error
对象的结构,例如使用{:?}
调试显示,显示该对象确实包含未修饰的错误字符串,但它似乎隐藏在内部字段中。
请注意,我的目标是提供便携式而非Linux专用解决方案。
答案 0 :(得分:1)
这是code添加“os error 2”:
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self.repr {
Repr::Os(code) => {
let detail = sys::os::error_string(code);
write!(fmt, "{} (os error {})", detail, code)
}
Repr::Custom(ref c) => c.error.fmt(fmt),
Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
}
}
}
不幸的是,sys::os::error_string
似乎无法访问,因此您必须将代码复制到您的程序中。
extern crate libc;
use std::ffi::CStr;
use std::fs;
use std::os::raw::{c_char, c_int};
use std::str;
const TMPBUF_SZ: usize = 128;
// from https://github.com/rust-lang/rust/blob/1.26.2/src/libstd/sys/unix/os.rs#L87-L107
pub fn error_string(errno: i32) -> String {
extern "C" {
#[cfg_attr(any(target_os = "linux", target_env = "newlib"), link_name = "__xpg_strerror_r")]
fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int;
}
let mut buf = [0 as c_char; TMPBUF_SZ];
let p = buf.as_mut_ptr();
unsafe {
if strerror_r(errno as c_int, p, buf.len()) < 0 {
panic!("strerror_r failure");
}
let p = p as *const _;
str::from_utf8(CStr::from_ptr(p).to_bytes())
.unwrap()
.to_owned()
}
}
fn main() {
let fl = "no such file";
if let Err(e) = fs::metadata(fl) {
eprintln!("{}: {}", fl, e);
eprintln!("{}", error_string(e.raw_os_error().unwrap()));
}
}
no such file: No such file or directory (os error 2)
No such file or directory