]>
Commit | Line | Data |
---|---|---|
94222f64 XL |
1 | //! Unix-specific extensions to general I/O primitives. |
2 | //! | |
3 | //! Just like raw pointers, raw file descriptors point to resources with | |
4 | //! dynamic lifetimes, and they can dangle if they outlive their resources | |
5 | //! or be forged if they're created from invalid values. | |
6 | //! | |
7 | //! This module provides three types for representing file descriptors, | |
8 | //! with different ownership properties: raw, borrowed, and owned, which are | |
9 | //! analogous to types used for representing pointers: | |
10 | //! | |
11 | //! | Type | Analogous to | | |
12 | //! | ------------------ | ------------ | | |
13 | //! | [`RawFd`] | `*const _` | | |
14 | //! | [`BorrowedFd<'a>`] | `&'a _` | | |
15 | //! | [`OwnedFd`] | `Box<_>` | | |
16 | //! | |
17 | //! Like raw pointers, `RawFd` values are primitive values. And in new code, | |
18 | //! they should be considered unsafe to do I/O on (analogous to dereferencing | |
19 | //! them). Rust did not always provide this guidance, so existing code in the | |
20 | //! Rust ecosystem often doesn't mark `RawFd` usage as unsafe. Once the | |
21 | //! `io_safety` feature is stable, libraries will be encouraged to migrate, | |
22 | //! either by adding `unsafe` to APIs that dereference `RawFd` values, or by | |
23 | //! using to `BorrowedFd` or `OwnedFd` instead. | |
24 | //! | |
25 | //! Like references, `BorrowedFd` values are tied to a lifetime, to ensure | |
26 | //! that they don't outlive the resource they point to. These are safe to | |
27 | //! use. `BorrowedFd` values may be used in APIs which provide safe access to | |
28 | //! any system call except for: | |
923072b8 | 29 | //! |
94222f64 XL |
30 | //! - `close`, because that would end the dynamic lifetime of the resource |
31 | //! without ending the lifetime of the file descriptor. | |
923072b8 | 32 | //! |
94222f64 XL |
33 | //! - `dup2`/`dup3`, in the second argument, because this argument is |
34 | //! closed and assigned a new resource, which may break the assumptions | |
35 | //! other code using that file descriptor. | |
923072b8 FG |
36 | //! |
37 | //! `BorrowedFd` values may be used in APIs which provide safe access to `dup` | |
38 | //! system calls, so types implementing `AsFd` or `From<OwnedFd>` should not | |
39 | //! assume they always have exclusive access to the underlying file | |
40 | //! description. | |
41 | //! | |
42 | //! `BorrowedFd` values may also be used with `mmap`, since `mmap` uses the | |
43 | //! provided file descriptor in a manner similar to `dup` and does not require | |
44 | //! the `BorrowedFd` passed to it to live for the lifetime of the resulting | |
45 | //! mapping. That said, `mmap` is unsafe for other reasons: it operates on raw | |
46 | //! pointers, and it can have undefined behavior if the underlying storage is | |
47 | //! mutated. Mutations may come from other processes, or from the same process | |
48 | //! if the API provides `BorrowedFd` access, since as mentioned earlier, | |
49 | //! `BorrowedFd` values may be used in APIs which provide safe access to any | |
50 | //! system call. Consequently, code using `mmap` and presenting a safe API must | |
51 | //! take full responsibility for ensuring that safe Rust code cannot evoke | |
52 | //! undefined behavior through it. | |
94222f64 XL |
53 | //! |
54 | //! Like boxes, `OwnedFd` values conceptually own the resource they point to, | |
55 | //! and free (close) it when they are dropped. | |
56 | //! | |
923072b8 FG |
57 | //! ## `/proc/self/mem` and similar OS features |
58 | //! | |
59 | //! Some platforms have special files, such as `/proc/self/mem`, which | |
60 | //! provide read and write access to the process's memory. Such reads | |
61 | //! and writes happen outside the control of the Rust compiler, so they do not | |
62 | //! uphold Rust's memory safety guarantees. | |
63 | //! | |
64 | //! This does not mean that all APIs that might allow `/proc/self/mem` | |
65 | //! to be opened and read from or written must be `unsafe`. Rust's safety guarantees | |
66 | //! only cover what the program itself can do, and not what entities outside | |
67 | //! the program can do to it. `/proc/self/mem` is considered to be such an | |
68 | //! external entity, along with debugging interfaces, and people with physical access to | |
69 | //! the hardware. This is true even in cases where the program is controlling | |
70 | //! the external entity. | |
71 | //! | |
72 | //! If you desire to comprehensively prevent programs from reaching out and | |
73 | //! causing external entities to reach back in and violate memory safety, it's | |
74 | //! necessary to use *sandboxing*, which is outside the scope of `std`. | |
75 | //! | |
94222f64 XL |
76 | //! [`BorrowedFd<'a>`]: crate::os::unix::io::BorrowedFd |
77 | ||
78 | #![stable(feature = "rust1", since = "1.0.0")] | |
79 | ||
80 | mod fd; | |
81 | mod raw; | |
82 | ||
923072b8 | 83 | #[stable(feature = "io_safety", since = "1.63.0")] |
94222f64 XL |
84 | pub use fd::*; |
85 | #[stable(feature = "rust1", since = "1.0.0")] | |
86 | pub use raw::*; |