Expand description
特定于 Unix 的通用 I/O 原语扩展。
就像裸指针一样,原始文件描述符指向具有动态生命周期的资源,如果它们比它们的资源生命周期更长,它们可以悬垂,如果它们是由无效值创建的,则它们可以被伪造。
该模块提供了三种用于表示文件描述符的类型,具有不同的所有权属性:原始、借用和拥有,类似于用于表示指针的类型:
Type | Analogous to |
---|---|
RawFd | *const _ |
BorrowedFd<'a> | &'a _ |
OwnedFd | Box<_> |
和裸指针一样,RawFd
值是原始值。
并且在新代码中,他们应该被认为是不安全的 (类似于解引用他们)。Rust 并不总是提供此指导,因此 Rust 生态系统中的现有代码通常不会将 RawFd
的使用标记为不安全。
一旦 io_safety
特性稳定,将鼓励库迁移,通过将 unsafe
添加到解引用 RawFd
值的 API,或者使用 BorrowedFd
或 OwnedFd
代替。
与引用一样,BorrowedFd
值与生命周期相关联,以确保它们的生命周期不会超过它们指向的资源。这些可以安全使用。
BorrowedFd
值可用于提供对任何系统调用的安全访问的 API 中,除了:
-
close
,因为这将结束资源的动态生命周期,而不结束文件描述符的生命周期。 -
dup2
/dup3
,在第二个参数中,因为这个参数被关闭并分配了一个新的资源,这可能会破坏其他代码使用该文件描述符的假设。
BorrowedFd
值可用于提供对 dup
系统调用的安全访问的 API,因此实现 AsFd
或 From<OwnedFd>
的类型不应假定它们始终具有对底层文件描述的独占访问权。
BorrowedFd
值也可以与 mmap
一起使用,因为 mmap
以类似于 dup
的方式使用提供的文件描述符,并且不需要传递给它的 BorrowedFd
在生成的映射的生命周期中存在。
也就是说,mmap
是不安全的还有其他原因:它在裸体疗法上运行,如果底层存储发生可变,它可能会有未定义的行为。
可变的可能来自其他进程,或者来自同一进程,如果 API 提供 BorrowedFd
访问,因为如前所述,BorrowedFd
值可能用于提供对任何系统调用的安全访问的 API。
因此,使用 mmap
并提供安全 API 的代码必须全权负责确保安全的 Rust 代码不会通过它引起未定义的行为。
与 box 一样,OwnedFd
在概念上拥有它们指向的资源,并在它们被丢弃时释放 X1X。
/proc/self/mem
和类似的操作系统特性
某些平台具有特殊文件,例如 /proc/self/mem
,它们提供对进程内存的读写访问。
此类读取和写入发生在 Rust 编译器的控制之外,因此它们不支持 Rust 的内存安全保证。
这并不意味着所有可能允许打开和读取或写入 /proc/self/mem
的 API 都必须是 unsafe
。
Rust 的安全保证只涵盖程序本身可以做的事情,而不包括程序外的实体可以对它做的事情。
/proc/self/mem
被认为是这样一个外部实体,连同调试接口,以及对硬件有物理访问权限的人。
即使在程序控制外部实体的情况下也是如此。
如果您希望全面防止程序伸出并导致外部实体再次进入并违反内存安全,则有必要使用 sandboxing,它不在 std
的作用域范围内。
Re-exports
pub use crate::os::fd::*;