How can I read from a specific raw file descriptor in Rust?

北城以北 提交于 2019-12-18 04:54:09

问题


Editor's note: This question is for a version of Rust prior to 1.0. Some answers have been updated to cover Rust 1.0 or up, but not all.

I am writing a systemd socket activated service in Rust. My process is being handed an open file descriptor by systemd.

Are there any Rust IO functions that take a raw file descriptor?

I'm using a Rust nightly before Rust 1.0.


回答1:


I think right now your best bet is probably using the libc crate for working with raw file descriptors.

The movement of FileDesc to private scope was fallout from the runtime removal a few months back. See this RFC for some more context. std::os::unix currently has the type Fd, and I believe the long term idea is to expose more of the platform-specific functionality in that module.




回答2:


As of Rust 1.1, you can use FromRawFd to create a File from a specific file descriptor, but only on UNIX-like operating systems:

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 is unsafe:

This function is also unsafe as the primitives currently returned have the contract that they are the sole owner of the file descriptor they are wrapping. Usage of this function could accidentally allow violating this contract which can cause memory unsafety in code that relies on it being true.

The created File will assume ownership of the file descriptor: when the File goes out of scope, the file descriptor will be closed. You can avoid this by using either IntoRawFd or mem::forget.

See also:

  • How do I write to a specific raw file descriptor from Rust?



回答3:


Editor's note: This answer is for a version of Rust prior to 1.0 and does not compile in Rust 1.0.

I'm just exploring rust myself, but after searching a bit, came up with the following use of the native crate: (using file descriptor "1" for the example -- 1 is 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);
}

(Tested with rustc 0.13.0-nightly. Note that the inner_write method may have been renamed to write in more recent versions of libstd)

Update

The nativecrate was recently removed from the standard library and FileDesc, while still exists as std::sys::fs::FileDesc is no longer public...



来源:https://stackoverflow.com/questions/27665396/how-can-i-read-from-a-specific-raw-file-descriptor-in-rust

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!