Как мне написать конкретный необработанный файловый дескриптор из Rust? - PullRequest
0 голосов
/ 25 февраля 2019

Мне нужно написать в файловый дескриптор 3. Я искал его, но документация довольно скудная.Единственное, что я нашел, - это использование библиотеки libc и метода fdopen, но я не нашел ни одного примера о том, как его использовать или писать на нем.

Может ли кто-нибудь дать мне пример записи дескриптора файла в Rust?

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Вы можете использовать FromRawFd для создания File из определенного файлового дескриптора, но только в UNIX-подобных операционных системах:

use std::{
    fs::File,
    io::{self, Write},
    os::unix::io::FromRawFd,
};

fn main() -> io::Result<()> {
    let mut f = unsafe { File::from_raw_fd(3) };
    write!(&mut f, "Hello, world!")?;
    Ok(())
}
$ target/debug/example 3> /tmp/output
$ cat /tmp/output
Hello, world!

from_raw_fd небезопасно, потому что нет гарантии, что дескриптор файла действителен или кто на самом деле отвечает за этот дескриптор файла.

Созданный File примет на себя владение файловым дескриптором: когда File выходит из области видимости, файловый дескриптор будет закрыт.Вы можете избежать этого, используя IntoRawFd или mem::forget.

См. Также:

0 голосов
/ 25 февраля 2019

Ящик libc является «просто» библиотекой обертки для взаимодействия между C и Rust, поэтому, чтобы узнать, как использовать функцию, нужно прочитать руководство по функции C, для этого есть много источников, здесь один для fdopen():

Функция fdopen() связывает поток с существующим файловым дескриптором, fd.Режим потока (одно из значений "r", "r+", "w", "w+", "a", "a+") должен быть совместим с режимом дескриптора файла.Индикатор положения файла в новом потоке устанавливается равным fd, а индикаторы ошибок и конца файла очищаются.Режимы "w" или "w+" не вызывают усечение файла.Дескриптор файла не дублируется и будет закрыт, когда поток, созданный с помощью fdopen(), будет закрыт.Результат применения fdopen() к объекту общей памяти не определен.

Основное использование таково:

use libc::fdopen;
use std::ffi::CString;

fn main() {
    let mode = CString::new("w").unwrap();
    unsafe {
        let _ = fdopen(3, mode.as_ptr());
    }
}

Чтобы использовать его, вы можете использовать fwrite():

Функция fwrite() записывает nmemb элементов данных, каждый размер длиной в байты, в поток, на который указывает поток, получая их из местоположения, заданного ptr.

Итак, полный пример:

use libc::{c_void, fdopen, fwrite};
use std::ffi::CString;

fn main() {
    let mode = CString::new("w").unwrap();
    let file = unsafe {
        let file = fdopen(3, mode.as_ptr());
        if file.is_null() {
            panic!("can't open file");
        }
        file
    };

    let welcome = "Hello world!";

    let result = unsafe { fwrite(welcome.as_ptr() as *const c_void, 1, welcome.len(), file) };
    if result != welcome.len() {
        panic!("write not successful");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...