如何从Rust中的特定原始文件描述符中读取?

squ*_*les 6 unix io file-descriptor rust

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

我在Rust中编写了一个systemd socket激活服务.我的进程被systemd传递给一个打开的文件描述符.

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

我在Rust 1.0之前每晚使用Rust.

crh*_*ino 5

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

FileDesc几个月前移除运行时后,私有作用域的移动会产生影响。有关更多上下文,请参阅此RFCstd::os::unix目前有 type Fd,我相信长期的想法是在该模块中公开更多特定于平台的功能。


She*_*ter 5

从 Rust 1.1 开始,您可以使用从特定文件描述符FromRawFd创建 a 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(())
}
Run Code Online (Sandbox Code Playgroud)
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(())
}
Run Code Online (Sandbox Code Playgroud)

from_raw_fd 不安全:

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

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

也可以看看: