如何从自定义文件描述符读取而不使用不安全?

时间:2019-06-12 18:18:12

标签: rust file-descriptor

this answer,我了解到可以使用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 个答案:

答案 0 :(得分:2)

您不能这样做。您唯一的途径就是使用unsafe

the documentation for FromRawFd中所述:

  

此函数也是不安全的,因为当前返回的原语具有它们是包装的文件描述符的唯一所有者的约定。使用此功能可能会意外地违反该合同,从而可能导致依赖于该合同为真的代码的内存不安全。

也许可以使用fcntl function来测试给定的描述符是否有效,但是我不知道有关在存在线程的情况下这些描述符如何工作的详细信息—有可能一个线程检查文件描述符的有效性并且有效,另一个线程将其关闭,然后第一个尝试使用它。这是简单明了的Time-of-check to time-of-use issue

另请参阅: