    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85

    //! The Unix `fcntl` function is effectively lots of different functions
    //! hidden behind a single dynamic dispatch interface. In order to provide
    //! a type-safe API, rustix makes them all separate functions so that they
    //! can have dedicated static type signatures.
    //!
    //! `fcntl` functions which are not specific to files or directories live
    //! in the [`io`] module instead.
    //!
    //! [`io`]: crate::io

    use crate::{backend, io};
    use backend::fd::{AsFd, OwnedFd, RawFd};

    pub use backend::io::types::FdFlags;

    /// `fcntl(fd, F_GETFD)`—Returns a file descriptor's flags.
    ///
    /// # References
    ///  - [POSIX]
    ///  - [Linux]
    ///
    /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html
    /// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html
    #[inline]
    #[doc(alias = "F_GETFD")]
    pub fn fcntl_getfd<Fd: AsFd>(fd: Fd) -> io::Result<FdFlags> {
        backend::io::syscalls::fcntl_getfd(fd.as_fd())
    }

    /// `fcntl(fd, F_SETFD, flags)`—Sets a file descriptor's flags.
    ///
    /// # References
    ///  - [POSIX]
    ///  - [Linux]
    ///
    /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html
    /// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html
    #[inline]
    #[doc(alias = "F_SETFD")]
    pub fn fcntl_setfd<Fd: AsFd>(fd: Fd, flags: FdFlags) -> io::Result<()> {
        backend::io::syscalls::fcntl_setfd(fd.as_fd(), flags)
    }

    /// `fcntl(fd, F_DUPFD_CLOEXEC)`—Creates a new `OwnedFd` instance, with value
    /// at least `min`, that has `O_CLOEXEC` set and that shares the same
    /// underlying [file description] as `fd`.
    ///
    /// POSIX guarantees that `F_DUPFD_CLOEXEC` will use the lowest unused file
    /// descriptor which is at least `min`, however it is not safe in general to
    /// rely on this, as file descriptors may be unexpectedly allocated on other
    /// threads or in libraries.
    ///
    /// # References
    ///  - [POSIX]
    ///  - [Linux]
    ///
    /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html
    /// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html
    #[cfg(not(any(target_os = "wasi", target_os = "espidf")))]
    #[inline]
    #[doc(alias = "F_DUPFD_CLOEXEC")]
    pub fn fcntl_dupfd_cloexec<Fd: AsFd>(fd: Fd, min: RawFd) -> io::Result<OwnedFd> {
        backend::io::syscalls::fcntl_dupfd_cloexec(fd.as_fd(), min)
    }

    /// `fcntl(fd, F_DUPFD)`—Creates a new `OwnedFd` instance, with value at least
    /// `min`, that shares the same underlying [file description] as `fd`.
    ///
    /// POSIX guarantees that `F_DUPFD` will use the lowest unused file descriptor
    /// which is at least `min`, however it is not safe in general to rely on this,
    /// as file descriptors may be unexpectedly allocated on other threads or in
    /// libraries.
    ///
    /// # References
    ///  - [POSIX]
    ///  - [Linux]
    ///
    /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html
    /// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html
    #[cfg(target_os = "espidf")]
    #[inline]
    #[doc(alias = "F_DUPFD")]
    pub fn fcntl_dupfd<Fd: AsFd>(fd: Fd, min: RawFd) -> io::Result<OwnedFd> {
        backend::io::syscalls::fcntl_dupfd(fd.as_fd(), min)
    }