编辑说明:该问题针对 Rust 1.0 之前的版本。有些答案已经更新以涵盖 Rust 1.0 或更高版本,但不是全部。
我正在使用 Rust 编写一个 systemd 套接字激活服务。我的进程从 systemd 获得了一个打开的文件描述符。
是否有任何 Rust IO 函数可以使用原始文件描述符?
我正在使用 Rust 1.0 之前的每夜版。
编辑说明:该问题针对 Rust 1.0 之前的版本。有些答案已经更新以涵盖 Rust 1.0 或更高版本,但不是全部。
我正在使用 Rust 编写一个 systemd 套接字激活服务。我的进程从 systemd 获得了一个打开的文件描述符。
是否有任何 Rust IO 函数可以使用原始文件描述符?
我正在使用 Rust 1.0 之前的每夜版。
FromRawFd
在类 UNIX 的操作系统上创建一个 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
来避免这种情况。
另请参见:
FileDesc
移动到私有范围是几个月前运行时删除的结果。请参阅RFC以获取更多上下文信息。 std::os::unix
目前具有类型Fd
,我相信长期想法是在该模块中公开更多平台特定功能。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
)
native
crate最近已从标准库中删除,而FileDesc
虽然仍存在于std::sys::fs::FileDesc
中,但不再是公共的...