Rust 来自原始fd的BufReader

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

我正在使用通过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();
这很好,但我想使用
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会有效,但我想象类似的东西已经存在了