从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
答案 0 :(得分:2)
您不能这样做。您唯一的途径就是使用unsafe
。
如the documentation for FromRawFd
中所述:
此函数也是不安全的,因为当前返回的原语具有它们是包装的文件描述符的唯一所有者的约定。使用此功能可能会意外地违反该合同,从而可能导致依赖于该合同为真的代码的内存不安全。
您 也许可以使用fcntl
function来测试给定的描述符是否有效,但是我不知道有关在存在线程的情况下这些描述符如何工作的详细信息—有可能一个线程检查文件描述符的有效性并且有效,另一个线程将其关闭,然后第一个尝试使用它。这是简单明了的Time-of-check to time-of-use issue。
另请参阅: