【问题标题】:How can I read from a specific raw file descriptor in Rust?如何从 Rust 中的特定原始文件描述符中读取?
【发布时间】:2014-12-27 07:45:57
【问题描述】:

编者注:这个问题是针对 1.0 之前的 Rust 版本。一些答案已更新以涵盖 Rust 1.0 或更高版本,但不是全部。

我正在用 Rust 编写一个 systemd 套接字激活服务。 systemd 正在向我的进程传递一个打开的文件描述符。

是否有任何采用原始文件描述符的 Rust IO 函数?

在 Rust 1.0 之前,我每晚都使用 Rust。

【问题讨论】:

    标签: unix io rust file-descriptor


    【解决方案1】:

    从 Rust 1.1 开始,您可以使用 FromRawFd 从特定文件描述符创建 File,但仅限于类 UNIX 操作系统:

    use std::{
        fs::File,
        io::{self, Read},
        os::unix::io::FromRawFd,
    };
    
    fn main() -> io::Result<()> {
        let mut f = unsafe { File::from_raw_fd(3) };
        let mut input = String::new();
        f.read_to_string(&mut input)?;
    
        println!("I read: {}", input);
    
        Ok(())
    }
    
    $ cat /tmp/output
    Hello, world!
    $ target/debug/example 3< /tmp/output
    I read: Hello, world!
    

    from_raw_fd 不安全:

    这个函数也是不安全的,因为当前返回的原语有一个约定,即它们是它们正在包装的文件描述符的唯一所有者。使用此函数可能会意外违反此约定,这可能会导致依赖它为 true 的代码中的内存不安全。

    创建的File 将承担文件描述符的所有权:当File 超出范围时,文件描述符将被关闭。您可以使用IntoRawFd 或mem::forget 来避免这种情况。

    另见:

    【讨论】:

      【解决方案2】:

      我认为现在你最好的选择可能是使用 libc crate 来处理原始文件描述符。

      FileDesc 移动到私有范围是几个月前运行时删除的后果。有关更多上下文,请参阅此RFC。 std::os::unix 当前具有 Fd 类型,我相信长期的想法是在该模块中公开更多特定于平台的功能。

      【讨论】:

      • 这个PR 也有更多的上下文。
      • 在 API 得到进一步开发之前,libc 似乎是一种可行的方法。
      【解决方案3】:

      编者注:此答案适用于 Rust 1.0 之前的版本,在 Rust 1.0 中无法编译。

      我自己只是在探索 rust,但在搜索了一下之后,想出了native crate 的以下用法:(以文件描述符“1”为例——1 是stdout)

      extern crate native;
      use native::io::file::FileDesc as FileDesc;
      
      fn main() 
      {
        let mut f = FileDesc::new(1, true);
        let buf = "Hello, world!\n".as_bytes();
      
        f.inner_write(buf);
      }
      

      (使用rustc 0.13.0-nightly 进行测试。请注意,inner_write 方法在更新的libstd 版本中可能已重命名为write)

      更新

      nativecrate 最近已从标准库和 FileDesc 中删除,但仍然存在,因为 std::sys::fs::FileDesc 不再公开...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-29
        • 1970-01-01
        • 2023-03-21
        相关资源
        最近更新 更多