Muszę napisać do deskryptora plików 3. Szukałem go, ale dokumentacja jest dość biedna. Jedyną rzeczą, którą znalazłem, jest użycie biblioteki {X0}} i metody fdopen, ale nie znalazłem żadnego przykładu, jak go używać lub pisać.

Czy ktoś może podać mi przykład pisania do deskryptora pliku w rdzy?

5
rdiaz82 25 luty 2019, 03:32

2 odpowiedzi

Najlepsza odpowiedź

Możesz użyć {x0}} do Utwórz File z określonego deskryptora pliku, Ale tylko na systemach operacyjnych podobnych do 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 jest niebezpieczny, ponieważ nie ma gwarancji, że deskryptor pliku jest ważny lub faktycznie odpowiedzialny za ten deskryptor pliku.

Utworzona File przyjmie własność deskryptora pliku: gdy File wychodzi poza zakres, deskryptor pliku zostanie zamknięty. Możesz tego uniknąć za pomocą IntoRawFd lub {x3}}.

Zobacz też:

10
Shepmaster 25 luty 2019, 14:49

Skrzynia libc jest "tylko" biblioteka owijania do interfejsu między C a rdzenią, aby wiedzieć, jak korzystać z funkcji, należy odczytać instrukcję obsługi C, istnieje wiele źródła, tutaj jeden dla {X1}}:

Funkcja fdopen() kojarzy strumień z istniejącym deskryptorem pliku, {x1}}. Tryb strumienia (jedna z wartości "r", "r+", "w", "w+", "w+", "a", "a+", musi być kompatybilny z Tryb deskryptora pliku. Wskaźnik położenia pliku wskaźniku nowego strumienia jest ustawiony na należąc do fd, a wskaźniki błędów i końcowych plików są wyczyszczone. Tryby "w" lub {{x10}} nie powodują obcięcia pliku. Deskryptor pliku nie jest DUP'ED i zostanie zamknięty, gdy strumień utworzony przez {{x11}} jest zamknięty. Wynik zastosowania fdopen() do obiektu pamięci współdzielonej jest niezdefiniowany.

Podstawowe użycie jest taka:

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

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

Aby go użyć, można użyć fwrite():

Funkcja fwrite() pisze nmemb elementy danych, każdy rozmiar bajtów wielkości, do strumienia wskazywanego przez strumień, uzyskanie ich z lokalizacji podanej przez ptr.

Pełny przykład:

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");
    }
}
2
Stargateur 25 luty 2019, 01:28