1b8a62b91Sopenharmony_ci//! Functions which duplicate file descriptors.
2b8a62b91Sopenharmony_ci
3b8a62b91Sopenharmony_ciuse crate::fd::OwnedFd;
4b8a62b91Sopenharmony_ciuse crate::{backend, io};
5b8a62b91Sopenharmony_ciuse backend::fd::AsFd;
6b8a62b91Sopenharmony_ci
7b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
8b8a62b91Sopenharmony_cipub use backend::io::types::DupFlags;
9b8a62b91Sopenharmony_ci
10b8a62b91Sopenharmony_ci/// `dup(fd)`—Creates a new `OwnedFd` instance that shares the same
11b8a62b91Sopenharmony_ci/// underlying [file description] as `fd`.
12b8a62b91Sopenharmony_ci///
13b8a62b91Sopenharmony_ci/// This function does not set the `O_CLOEXEC` flag. To do a `dup` that does
14b8a62b91Sopenharmony_ci/// set `O_CLOEXEC`, use [`fcntl_dupfd_cloexec`].
15b8a62b91Sopenharmony_ci///
16b8a62b91Sopenharmony_ci/// POSIX guarantees that `dup` will use the lowest unused file descriptor,
17b8a62b91Sopenharmony_ci/// however it is not safe in general to rely on this, as file descriptors may
18b8a62b91Sopenharmony_ci/// be unexpectedly allocated on other threads or in libraries.
19b8a62b91Sopenharmony_ci///
20b8a62b91Sopenharmony_ci/// # References
21b8a62b91Sopenharmony_ci///  - [POSIX]
22b8a62b91Sopenharmony_ci///  - [Linux]
23b8a62b91Sopenharmony_ci///  - [Apple]
24b8a62b91Sopenharmony_ci///
25b8a62b91Sopenharmony_ci/// [file description]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_258
26b8a62b91Sopenharmony_ci/// [`fcntl_dupfd_cloexec`]: crate::io::fcntl_dupfd_cloexec
27b8a62b91Sopenharmony_ci/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup.html
28b8a62b91Sopenharmony_ci/// [Linux]: https://man7.org/linux/man-pages/man2/dup.2.html
29b8a62b91Sopenharmony_ci/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/dup.2.html
30b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
31b8a62b91Sopenharmony_ci#[inline]
32b8a62b91Sopenharmony_cipub fn dup<Fd: AsFd>(fd: Fd) -> io::Result<OwnedFd> {
33b8a62b91Sopenharmony_ci    backend::io::syscalls::dup(fd.as_fd())
34b8a62b91Sopenharmony_ci}
35b8a62b91Sopenharmony_ci
36b8a62b91Sopenharmony_ci/// `dup2(fd, new)`—Changes the [file description] of a file descriptor.
37b8a62b91Sopenharmony_ci///
38b8a62b91Sopenharmony_ci/// `dup2` conceptually closes `new` and then sets the file description for
39b8a62b91Sopenharmony_ci/// `new` to be the same as the one for `fd`. This is a very unusual operation,
40b8a62b91Sopenharmony_ci/// and should only be used on file descriptors where you know how `new` will
41b8a62b91Sopenharmony_ci/// be subsequently used.
42b8a62b91Sopenharmony_ci///
43b8a62b91Sopenharmony_ci/// This function does not set the `O_CLOEXEC` flag. To do a `dup2` that does
44b8a62b91Sopenharmony_ci/// set `O_CLOEXEC`, use [`dup3`] with [`DupFlags::CLOEXEC`] on platforms which
45b8a62b91Sopenharmony_ci/// support it, or [`fcntl_dupfd_cloexec`]
46b8a62b91Sopenharmony_ci///
47b8a62b91Sopenharmony_ci/// # References
48b8a62b91Sopenharmony_ci///  - [POSIX]
49b8a62b91Sopenharmony_ci///  - [Linux]
50b8a62b91Sopenharmony_ci///  - [Apple]
51b8a62b91Sopenharmony_ci///
52b8a62b91Sopenharmony_ci/// [file description]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_258
53b8a62b91Sopenharmony_ci/// [`fcntl_dupfd_cloexec`]: crate::io::fcntl_dupfd_cloexec
54b8a62b91Sopenharmony_ci/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/dup2.html
55b8a62b91Sopenharmony_ci/// [Linux]: https://man7.org/linux/man-pages/man2/dup2.2.html
56b8a62b91Sopenharmony_ci/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/dup2.2.html
57b8a62b91Sopenharmony_ci#[cfg(not(target_os = "wasi"))]
58b8a62b91Sopenharmony_ci#[inline]
59b8a62b91Sopenharmony_cipub fn dup2<Fd: AsFd>(fd: Fd, new: &mut OwnedFd) -> io::Result<()> {
60b8a62b91Sopenharmony_ci    backend::io::syscalls::dup2(fd.as_fd(), new)
61b8a62b91Sopenharmony_ci}
62b8a62b91Sopenharmony_ci
63b8a62b91Sopenharmony_ci/// `dup3(fd, new, flags)`—Changes the [file description] of a file
64b8a62b91Sopenharmony_ci/// descriptor, with flags.
65b8a62b91Sopenharmony_ci///
66b8a62b91Sopenharmony_ci/// `dup3` is the same as [`dup2`] but adds an additional flags operand, and it
67b8a62b91Sopenharmony_ci/// fails in the case that `fd` and `new` have the same file descriptor value.
68b8a62b91Sopenharmony_ci/// This additional difference is the reason this function isn't named
69b8a62b91Sopenharmony_ci/// `dup2_with`.
70b8a62b91Sopenharmony_ci///
71b8a62b91Sopenharmony_ci/// # References
72b8a62b91Sopenharmony_ci///  - [Linux]
73b8a62b91Sopenharmony_ci///
74b8a62b91Sopenharmony_ci/// [file description]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_258
75b8a62b91Sopenharmony_ci/// [Linux]: https://man7.org/linux/man-pages/man2/dup3.2.html
76b8a62b91Sopenharmony_ci#[cfg(not(any(target_os = "aix", target_os = "wasi")))]
77b8a62b91Sopenharmony_ci#[inline]
78b8a62b91Sopenharmony_cipub fn dup3<Fd: AsFd>(fd: Fd, new: &mut OwnedFd, flags: DupFlags) -> io::Result<()> {
79b8a62b91Sopenharmony_ci    backend::io::syscalls::dup3(fd.as_fd(), new, flags)
80b8a62b91Sopenharmony_ci}
81