rust - 来自原始 fd 的 BufReader
问题描述
我正在使用fdpass crate通过 unix 套接字将文件描述符从一个进程发送到另一个进程(我不关心兼容性,只有 unix 就可以了)。
使用 mio 我设法监听这些文件描述符上的事件:
let fd = fdpass::recv_fd(&mut client, vec!(0u8)).unwrap();
let efd = EventedFd(&fd.into_raw_fd());
poll.register(&efd, Token(0), Ready::readable(), PollOpt::level()).unwrap();
这工作得很好,但我想使用 aBufReader
逐行读取该文件描述符。我一直在试图找出一种方法来使用from_raw_fd()
可能无法成功实施的BufReader
东西。它似乎只存在于文件或网络流之类的东西上。唯一的另一件事是Stdio
它没有实现 Read,对于BufRead
.
关于如何BufReader
从原始 fd 中获取 a 而不会使 mio 使用不安全的任何建议?
顺便说一句,文件描述符不是文件(尽管它们可能在某些时候存在)所以我不能使用File::
,现在我只是通过 fdpass 将客户端的标准输入作为原始 fd 发送。
解决方案
不幸FromRawFd
的是,只为充满 structs 的手实现。你需要事先知道你想读取什么样的“文件”,否则你会冒未定义行为的风险(因为 Rust 假设 FD 是一种它不是的类型)。
但是,您可以实现自己的结构,该结构除了读取适用于所有文件描述符之外什么都不做。这可以通过对 的函数调用来完成man (2) read
。
use libc;
use std::ffi::OsStr;
use std::io::{Error, Read, Result};
use std::os::unix::ffi::OsStrExt;
use std::os::unix::io::{FromRawFd, RawFd};
pub struct RawFdReader {
fd: RawFd,
}
impl FromRawFd for RawFdReader {
unsafe fn from_raw_fd(fd: RawFd) -> Self {
Self { fd }
}
}
impl Read for RawFdReader {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
assert!(buf.len() <= isize::max_value() as usize);
match unsafe { libc::read(self.fd, buf.as_mut_ptr() as _, buf.len()) } {
x if x < 0 => Err(Error::last_os_error()),
x => Ok(x as usize),
}
}
}
fn main() -> Result<()> {
let mut reader = unsafe { RawFdReader::from_raw_fd(0) };
let mut buffer = vec![0; 10];
let len = reader.read(&mut buffer)?;
println!("{:?}", OsStr::from_bytes(&buffer[..len]));
Ok(())
}
推荐阅读
- angular - 我可以在 ngx-intl-tel-input 中显示标签吗?
- stm32 - 配置时无法访问STM32 DMA寄存器
- angular - 禁用/关闭 Angular ESLint“不应否定异步管道结果”
- flutter - Flutter Listivew 主题标签显示更多问题
- c - 是否有一种标准方法可以在编译时检查该文件是否仅被预处理?
- python - 如何使用python(Selenium)刷新页面直到元素可用?
- react-native - EPSG:4326 格式的 react-native-maps WMSTile
- reactjs - onClickHandler 有时有效,有时无效 - React
- c - 使用while循环的scanf用户输入
- javascript - Nextjs 页面刷新总是把我带到 index.js