Change:
In std::io, : Note that exclusive ownership of a file descriptor does not imply exclusive ownership of the underlying kernel object that the file descriptor references (also called “file description” on some operating systems). File descriptors basically work like : when you receive an owned file descriptor, you cannot know whether there are any other file descriptors that reference the same kernel object. However, when you create a new kernel object, you know that you are holding the only reference to it. Just be careful not to lend it to anyone, since they can obtain a clone and then you can no longer know what the reference count is! In that sense, is like Arc and is like &'a Arc However the table in std::io::unix::io has the table saying: =Box<This is incorrect and potentially very misleading, because the result of ping a file descriptor creates a new fd which shares the same underlying file structure in the kernel. In particular, for seekable fds they share the current file offset (ie, used by and ) and in some cases, file locking state. (In addition to inode state and underlying file/pipe/etc contents.) The language here should reflect the language in std::io.
cc - I think this is something that should have addressed.
Yeah the model described in doesn't take into account and the indirection layer of "file descriptors" vs "file descriptions". (That was already the case before though, it just became a lot more apparent with that PR.)

Discussion:
//! its file descriptors with no operations being performed by any other part of the program. //! //! Note that exclusive ownership of a file descriptor does *not* imply exclusive ownership of the <del> //! underlying kernel object that the file descriptor references (also called "file description" on </del> <ins> //! underlying kernel object that the file descriptor references (also called "open file description" on </ins> //! some operating systems). File descriptors basically work like [`Arc`]: when you receive an owned //! file descriptor, you cannot know whether there are any other file descriptors that reference the //! same kernel object. However, when you create a new kernel object, you know that you are holding

//! | Type               | Analogous to | //! | ------------------ | ------------ | //! | [`RawFd`]          | `*const _`   | <del> //! | [`BorrowedFd<'a>`] | `&'a _`      | //! | [`OwnedFd`]        | `Box<_>`     | </del> <ins> //! | [`BorrowedFd<'a>`] | `&'a Arc<_>` | //! | [`OwnedFd`]        | `Arc<_>`     | </ins> //! //! 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

//! either by adding `unsafe` to APIs that dereference `RawFd` values, or by //! using to `BorrowedFd` or `OwnedFd` instead. //! <ins> //! The use of `Arc` for borrowed/owned file descriptors may be surprising. Unix file descriptors //! are mere references to internal kernel objects called "open file descriptions", and the same //! open file description can be referenced by multiple file descriptors (e.g. if `dup` is used). //! State such as the offset within the file is shared among all file descriptors that refer to the //! same open file description, and the kernel internally does reference-counting to only close the //! underlying resource once all file descriptors referencing it are closed. That's why `Arc` (and //! not `Box`) is the closest Rust analogy to an "owned" file descriptor. //! </ins> //! 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 <del> //!    without ending the lifetime of the file descriptor. </del> <ins> //!    without ending the lifetime of the file descriptor. (Equivalently: //!    an `&Arc<_>` cannot be `drop`ed.) </ins> //! //!  - `dup2`/`dup3`, in the second argument, because this argument is <del> //!    closed and assigned a new resource, which may break the assumptions </del> <ins> //!    closed and assigned a new resource, which may break the assumptions of </ins> //!    other code using that file descriptor. //! <del> //! `BorrowedFd` values may be used in APIs which provide safe access to `dup` //! system calls, so types implementing `AsFd` or `From<OwnedFd>` should not //! assume they always have exclusive access to the underlying file //! description. </del> <ins> //! `BorrowedFd` values may be used in APIs which provide safe access to `dup` system calls, so code //! working with `OwnedFd` cannot assume to have exclusive access to the underlying open file //! description. (Equivalently: `&Arc` may be used in APIs that provide safe access to `clone`, so //! code working with an `Arc` cannot assume that the reference count is 1.) </ins> //! //! `BorrowedFd` values may also be used with `mmap`, since `mmap` uses the //! provided file descriptor in a manner similar to `dup` and does not require

//! take full responsibility for ensuring that safe Rust code cannot evoke //! undefined behavior through it. //! <del> //! Like boxes, `OwnedFd` values conceptually own the resource they point to, //! and free (close) it when they are dropped. </del> <ins> //! Like `Arc`, `OwnedFd` values conceptually own one reference to the resource they point to, //! and decrement the reference count when they are dropped (by calling `close`). //! When the reference count reaches 0, the underlying open file description will be freed //! by the kernel. </ins> //! //! See the [`io` module docs][io-safety] for a general explanation of I/O safety. //!