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