Как читать из пользовательских файловых дескрипторов без использования небезопасных? - PullRequest
1 голос
/ 12 июня 2019

Из этого ответа я узнал, что дескриптор файла можно прочитать с помощью unsafe:

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!

Как мне достичь того же результата, не используя unsafe?

В настоящее время я создаю дескриптор файла, подобный этому (zsh shell):

function test_fd {
   if ! read -r line <&$1; then
       line="[Read on fd $1 failed]"
   fi

   echo $line

   # Remove the handler and close the fd
   zle -F $1
   exec {1}<&-
}

exec {FD}< <(/path/to/my/app)
zle -F $FD test_fd

Я хотел бы заменить test_fd чем-то, что могло бы read или лучше, если бы оно могло read & close предоставленным дескриптором файла, чтобы я мог закончить чем-то вроде:

function test_fd {
   /something/in/rust "$@"
}

exec {FD}< <(/path/to/my/app)
zle -F $FD test_fd

1 Ответ

2 голосов
/ 12 июня 2019

Вы не можете сделать это.Ваша единственная возможность - использовать unsafe.

Как указано в документации для FromRawFd:

Эта функция также небезопасна, так как примитивы в настоящее времявозвращен контракт, который является единственным владельцем дескриптора файла, который они переносят.Использование этой функции может случайно привести к нарушению этого контракта, что может привести к небезопасной памяти в коде, который полагается на его истинность.

Вы можете иметь возможность использовать fcntl функция для проверки правильности заданного дескриптора, но я не знаю подробностей о том, как они работают при наличии потоков - возможно, что один поток проверяет правильность дескриптора файла, и он действителен, другой поток закрывает его, затем первый пытается использовать его.Это просто Время проверки на время использования вопроса .

См. Также:

...