Rust系统编程: 查看最近的一次系统调用发生的错误

每个线程都有一个 errno

use std::fs;
use libc;
use nix;

// 标准库或nix库都会把Path/&str转成CStr,转换后会自动加上\0终止符,所以转换时强制要求File::open的路径字符串不得有\0从而避免重复的\0终止符
// libc 库, 需要自己手动转换 添加\0

fn main(){
    unsafe {
        let PATH = "testfile";  // 这个文件权限 000
        let f = fs::File::open(PATH);
        println!("打开一个不存在的文件: {:?}", f);  // 这个使用标准库返回的还算清晰, code: 2 表示错误码是2


        // 使用libc库, 一个发生错误的系统调用
        let PATH = "testfile\0";
        let f = libc::mkfifo(PATH.as_ptr() as _, libc::S_IREAD);
        println!("使用libc库 libc::mkfifo中的错误信息: {:?}", f);  // 这个返回和上面的比就不行了, 只返回了一个 -1
        // 使用 errno相关函数获取最近一次系统调用的错误码  libc::__errno_location这个函数, 但是在 mac系统中 没有这个功能
        println!("使用nix库, 查看最近一次系统调用的错误码: {}", nix::errno::errno());  // 17:File exists

        // 使用nix库 一个发生错误的系统调用, nix的错误处理更符合rust风格, 他是对libc更进一步的封装
        // nix 库通过对 libc 库暴露的 unsafe API 进行封装, 为 libc 库支持的某些平台提供了一种 safe的替代方案
        let PATH = "testfile";
        let f = nix::unistd::mkfifo(PATH, nix::sys::stat::Mode::S_IRWXU);
        println!("使用nix库, libc::mkfifo中的错误信息: {:?}", f);  // 返回的清晰明了 Err(EEXIST)
        println!("使用nix库, 查看最近一次系统调用的错误码: {}", nix::errno::errno())  // 17:File exists
    }

}