Как я могу прочитать из необработанного дескриптора файла?

Я пишу активированный сокетом systemd сервис в Rust. Мой процесс передается дескриптором открытого файла systemd.

Существуют ли какие-либо функции Rust IO, которые принимают необработанный файловый дескриптор?

Изменить: я использую Rust по ночам.

2 ответа

Решение

Я думаю, что сейчас лучшим вариантом будет использование библиотеки libc для работы с необработанными файловыми дескрипторами.

Движение FileDesc в частную сферу были последствия от удаления времени выполнения несколько месяцев назад. Посмотрите этот RFC для некоторого большего контекста. std::os::unix в настоящее время имеет тип Fdи я считаю, что долгосрочная идея состоит в том, чтобы в этом модуле раскрыть больше функций, специфичных для платформы.

Начиная с Rust 1.1, вы можете использовать FromRawFd создать 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,

Смотрите также:

Я просто исследую ржавчину сам, но после небольшого поиска, придумал следующее использование 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 метод, возможно, был переименован в write в более поздних версиях libstd)

Обновить

nativeящик был недавно удален из стандартной библиотеки и FileDescпока еще существует как std::sys::fs::FileDesc больше не публично...

Другие вопросы по тегам