rust - 如何获取系统提供的没有 "os error n"后缀的错误消息?

标签 rust

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)

如何获取系统提供的系统错误消息,即没有“操作系统错误 2”部分?

我试过:

  • 调用 e.description(),返回不同的错误消息(“未找到实体”),这很有用,但不是我要找的;

  • 检查 Error 对象的结构,例如使用 {:?} 调试显示,显示对象确实包含未修饰的错误字符串,但它似乎隐藏在内部字段中。

请注意,我的目标是可移植的而非仅限 Linux 的解决方案。

最佳答案

这是 code添加“操作系统错误 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()));
    }
}

Output :

no such file: No such file or directory (os error 2)
No such file or directory

关于rust - 如何获取系统提供的没有 "os error n"后缀的错误消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40710115/

相关文章:

rust - 如何制作可以反序列化为多种类型之一的 config.rs 字段?

rust - "use of undeclared type or module"当使用 Diesel 's ` belongs_to` 属性

loops - loop 和 while true 有什么区别?

rust - 有没有办法让一个特征在它扩展的另一个特征中为关联类型指定自己?

rust - Handlebars 三个阵列在一个循环中

enums - 我应该使用枚举还是盒装特征对象来模拟多态性?

vector - 如何匹配迭代器的项目?

rust - 如何习惯性地将Option <T>转换为Result <T,()>?

rust - 宏是否可以采用常量表达式和 "inline"来生成有效的 LiteralPattern?

visual-studio-code - 为什么我在编译时没有反射(reflect)出我从 VS Code 对 Rust 程序所做的更改?