【问题标题】:How to read from custom file descriptors without using unsafe?如何在不使用不安全的情况下从自定义文件描述符中读取?
【发布时间】:2019-06-12 18:18:12
【问题描述】:

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 &amp; close 提供的文件描述符则更好,这样我就可以以如下内容结束:

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

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

【问题讨论】:

标签: rust file-descriptor


【解决方案1】:

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

the documentation for FromRawFd中所述:

这个函数也是不安全的,因为当前返回的原语有一个约定,即它们是它们正在包装的文件描述符的唯一所有者。使用此函数可能会意外违反此约定,这可能会导致依赖它为 true 的代码中的内存不安全。

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

另见:

【讨论】:

  • 在这些情况下如何处理unsafe?如果文件描述符无效等,有没有办法“捕获/捕获”?
  • 我不清楚 UB 是从哪里来的,但我对系统调用也不太了解,无法知道在坏 FD 上执行 IO 时会出现什么问题。像 CPython 解释器这样的“安全”构造如何处理这样的事情?
  • @turbulencetoo 这是一个好点;我收到了有关无效文件描述符的错误消息,因此可能会在操作系统级别进行一些检查以防止这种情况发生。我会看看是否可以使该文本更准确。
  • @turbulencetoo 我已经更新为使用文档的确切措辞,它使用“内存不安全”而不是“未定义的行为”
猜你喜欢
  • 2019-05-19
  • 1970-01-01
  • 1970-01-01
  • 2011-04-19
  • 1970-01-01
  • 2018-08-12
  • 1970-01-01
  • 1970-01-01
  • 2017-08-01
相关资源
最近更新 更多