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)
}