来自 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
替换为可以读取
的内容,或者如果它可以读取并关闭
提供的文件描述符则更好,这样我可以这样结束:
function test_fd {
/something/in/rust "$@"
}
exec {FD}< <(/path/to/my/app)
zle -F $FD test_fd
最佳答案
你不能这样做。您唯一的途径是使用 unsafe
。
如 the documentation for FromRawFd
中所述:
This function is also unsafe as the primitives currently returned have the contract that they are the sole owner of the file descriptor they are wrapping. Usage of this function could accidentally allow violating this contract which can cause memory unsafety in code that relies on it being true.
您可能能够利用 fcntl
function测试给定的描述符是否有效,但我不知道这些在线程存在的情况下如何工作的细节——一个线程可能检查文件描述符的有效性并且它是有效的,另一个线程关闭它,然后首先尝试使用它。这是一个直截了当的 Time-of-check to time-of-use issue .
另见:
关于rust - 如何在不使用不安全的情况下读取自定义文件描述符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56568186/