Rust 来自原始fd的BufReader
我正在使用通过unix套接字将文件描述符从一个进程发送到另一个进程(我不关心兼容性,只考虑unix) 使用mio,我可以监听这些文件描述符上的事件:Rust 来自原始fd的BufReader,rust,Rust,我正在使用通过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
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();
这很好,但我想使用BufReader
逐行读取文件描述符。我一直在试图找到一种方法,将from_raw\u fd()
用于将实现BufReader
的东西,但没有成功。它似乎只存在于文件或网络流之类的东西中。唯一的另一件事是Stdio
,它不实现读取,这是BufRead
所必需的
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(())
}
关于如何从原始fd获得BufReader
而不使mio使用不安全,有什么建议吗
顺便说一句,文件描述符不是文件(尽管在某些情况下可能是),所以我不能使用
文件::
,现在我只是通过fdpass将客户机的stdin作为原始fd发送。不幸的是FromRawFd
仅为一个应用程序实现。您需要事先知道要读取什么类型的“文件”,否则可能会出现未定义的行为(因为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(())
}
使用libc;
使用std::ffi::OsStr;
使用std::io::{Error,Read,Result};
使用std::os::unix::ffi::OsStrExt;
使用std::os::unix::io:{FromRawFd,RawFd};
pub结构RawFdReader{
fd:RawFd,
}
针对RawFdReader的impl FromRawFd{
来自原始fd(fd:RawFd)->自身的不安全fn{
自{fd}
}
}
RawFdReader的impl Read{
fn读取(&mut self,buf:&mut[u8])->结果{
断言!(buf.len()Err(Error::last_os_Error()),
x=>Ok(x为usize),
}
}
}
fn main()->结果{
设mut reader=unsafe{RawFdReader::from_raw_fd(0)};
让mut buffer=vec![0;10];
设len=reader.read(&mut buffer)?;
println!(“{:?}”,OsStr::from_字节(&buffer[…len]);
好(())
}
如果您实现一个静态方法(例如new
),当然可以摆脱不安全的{RawFdReader::from_raw\u fd(0)}
)然后在那里传递一个RawFd
,因为你知道它是安全的。看起来这确实很好,非常感谢!我认为直接使用read会有效,但我想象类似的东西已经存在了