about summary refs log tree commit diff
path: root/library/std/src/os/unix/io/mod.rs
diff options
context:
space:
mode:
authorDan Gohman <dev@sunfishcode.online>2021-06-30 21:44:30 -0700
committerDan Gohman <dev@sunfishcode.online>2021-08-19 12:02:39 -0700
commitd15418586ca78ead4f87ad18fcffa3550c1b169e (patch)
tree93234d47e5eab3c9177ad31b9369abcd1c1ed5d1 /library/std/src/os/unix/io/mod.rs
parent2451f42c1deb9379d5e8e5fa86b0bf857ae048ec (diff)
downloadrust-d15418586ca78ead4f87ad18fcffa3550c1b169e.tar.gz
rust-d15418586ca78ead4f87ad18fcffa3550c1b169e.zip
I/O safety.
Introduce `OwnedFd` and `BorrowedFd`, and the `AsFd` trait, and
implementations of `AsFd`, `From<OwnedFd>` and `From<T> for OwnedFd`
for relevant types, along with Windows counterparts for handles and
sockets.

Tracking issue:
 - <https://github.com/rust-lang/rust/issues/87074>

RFC:
 - <https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md>
Diffstat (limited to 'library/std/src/os/unix/io/mod.rs')
-rw-r--r--library/std/src/os/unix/io/mod.rs56
1 files changed, 56 insertions, 0 deletions
diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs
new file mode 100644
index 00000000000..06f47cbb31f
--- /dev/null
+++ b/library/std/src/os/unix/io/mod.rs
@@ -0,0 +1,56 @@
+//! Unix-specific extensions to general I/O primitives.
+//!
+//! Just like raw pointers, raw file descriptors point to resources with
+//! dynamic lifetimes, and they can dangle if they outlive their resources
+//! or be forged if they're created from invalid values.
+//!
+//! This module provides three types for representing file descriptors,
+//! with different ownership properties: raw, borrowed, and owned, which are
+//! analogous to types used for representing pointers:
+//!
+//! | Type               | Analogous to |
+//! | ------------------ | ------------ |
+//! | [`RawFd`]          | `*const _`   |
+//! | [`BorrowedFd<'a>`] | `&'a _`      |
+//! | [`OwnedFd`]        | `Box<_>`     |
+//!
+//! Like raw pointers, `RawFd` values are primitive values. And in new code,
+//! they should be considered unsafe to do I/O on (analogous to dereferencing
+//! them). Rust did not always provide this guidance, so existing code in the
+//! Rust ecosystem often doesn't mark `RawFd` usage as unsafe. Libraries are
+//! encouraged to migrate, either by adding `unsafe` to APIs that dereference
+//! `RawFd` values, or by using to `BorrowedFd` or `OwnedFd` instead.
+//!
+//! Like references, `BorrowedFd` values are tied to a lifetime, to ensure
+//! that they don't outlive the resource they point to. These are safe to
+//! use. `BorrowedFd` values may be used in APIs which provide safe access to
+//! any system call except for:
+//!  - `close`, because that would end the dynamic lifetime of the resource
+//!    without ending the lifetime of the file descriptor.
+//!  - `dup2`/`dup3`, in the second argument, because this argument is
+//!    closed and replaced with a new resource, which may break the assumptions
+//!    other code using that file descriptor.
+//! This list doesn't include `mmap`, since `mmap` does do a proper borrow of
+//! its file descriptor argument. That said, `mmap` is unsafe for other
+//! reasons: it operates on raw pointers, and it has undefined behavior if the
+//! underlying storage is mutated. Mutations may come from other processes, or
+//! from the same process if the API provides `BorrowedFd` access, since as
+//! mentioned earlier, `BorrowedFd` values may be used in APIs which provide
+//! safe access to any system call. Consequently, code using `mmap` and
+//! presenting a safe API must take full responsibility for ensuring that safe
+//! Rust code cannot evoke undefined behavior through it.
+//!
+//! Like boxes, `OwnedFd` values conceptually own the resource they point to,
+//! and free (close) it when they are dropped.
+//!
+//! [`BorrowedFd<'a>`]: crate::os::unix::io::BorrowedFd
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+mod fd;
+mod raw;
+
+#[unstable(feature = "io_safety", issue = "87074")]
+pub use fd::*;
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use raw::*;