编者注:此问题适用于1.0之前的Rust版本。一些答案已经更新,以涵盖Rust 1.0或更高版本,但不是全部。
我在Rust中编写了一个systemd socket激活服务。我的进程被systemd传递给一个打开的文件描述符。
是否有任何带有原始文件描述符的Rust IO函数?
我在Rust 1.0之前每晚使用Rust。
答案 0 :(得分:2)
我认为现在最好的办法是使用libc crate来处理原始文件描述符。
几个月前,FileDesc
向私有范围的移动与运行时删除相关。有关更多上下文,请参阅此RFC。 std::os::unix
目前的类型为Fd
,我认为长期的想法是在该模块中公开更多特定于平台的功能。
答案 1 :(得分: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
超出范围时,文件描述符将被关闭。您可以使用IntoRawFd
或mem::forget
来避免这种情况。
另请参阅:
答案 2 :(得分:0)
编者注:这个答案适用于1.0之前的Rust版本,不能在Rust 1.0中编译。
我自己正在探索生锈,但在搜索了一下之后,想出了native
crate的以下用法:(使用文件描述符&#34; 1&#34;例如 - - 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
native
crate最近已从标准库和FileDesc
中移除,但仍然存在,因为std::sys::fs::FileDesc
已不再公开......