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

问题描述 投票:5回答:3

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

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

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

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

unix io rust file-descriptor
3个回答
2
投票

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

FileDesc移动到私人范围是几个月前从运行时删除的影响。有关更多背景信息,请参阅此RFCstd::os::unix目前的类型为Fd,我认为长期的想法是在该模块中公开更多特定于平台的功能。


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不安全:

此函数也不安全,因为当前返回的基元具有它们是它们包装的文件描述符的唯一所有者的契约。使用此函数可能会意外地违反此合同,这可能会导致依赖于此操作的代码中的内存不安全。

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

也可以看看:


0
投票

编者注:这个答案适用于1.0之前的Rust版本,不能在Rust 1.0中编译。

我只是自己探索生锈,但经过一番搜索后,想出了以下native箱子的使用方法:(使用文件描述符“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方法可能已在更新版本的write中重命名为libstd

更新

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

© www.soinside.com 2019 - 2024. All rights reserved.