Как я могу прочитать из необработанного дескриптора файла?
Я пишу активированный сокетом 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
больше не публично...