rustix/fs/fcntl.rs
1//! The Unix `fcntl` function is effectively lots of different functions hidden
2//! behind a single dynamic dispatch interface. In order to provide a type-safe
3//! API, rustix makes them all separate functions so that they can have
4//! dedicated static type signatures.
5
6#[cfg(not(any(
7 target_os = "emscripten",
8 target_os = "espidf",
9 target_os = "fuchsia",
10 target_os = "horizon",
11 target_os = "redox",
12 target_os = "vita",
13 target_os = "wasi"
14)))]
15use crate::fs::FlockOperation;
16use crate::{backend, io};
17use backend::fd::AsFd;
18use backend::fs::types::OFlags;
19
20/// `fcntl(fd, F_GETFL)`—Returns a file descriptor's access mode and status.
21///
22/// # References
23/// - [POSIX]
24/// - [Linux]
25///
26/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fcntl.html
27/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html
28#[inline]
29#[doc(alias = "F_GETFL")]
30pub fn fcntl_getfl<Fd: AsFd>(fd: Fd) -> io::Result<OFlags> {
31 backend::fs::syscalls::fcntl_getfl(fd.as_fd())
32}
33
34/// `fcntl(fd, F_SETFL, flags)`—Sets a file descriptor's status.
35///
36/// # References
37/// - [POSIX]
38/// - [Linux]
39///
40/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fcntl.html
41/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html
42#[inline]
43#[doc(alias = "F_SETFL")]
44pub fn fcntl_setfl<Fd: AsFd>(fd: Fd, flags: OFlags) -> io::Result<()> {
45 backend::fs::syscalls::fcntl_setfl(fd.as_fd(), flags)
46}
47
48/// `fcntl(fd, F_GET_SEALS)`—Return the seals for `fd`'s inode.
49///
50/// # References
51/// - [Linux]
52///
53/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html
54#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
55#[inline]
56#[doc(alias = "F_GET_SEALS")]
57pub fn fcntl_get_seals<Fd: AsFd>(fd: Fd) -> io::Result<SealFlags> {
58 backend::fs::syscalls::fcntl_get_seals(fd.as_fd())
59}
60
61#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
62use backend::fs::types::SealFlags;
63
64/// `fcntl(fd, F_ADD_SEALS)`—Add seals to `fd`'s inode.
65///
66/// # References
67/// - [Linux]
68///
69/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html
70#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))]
71#[inline]
72#[doc(alias = "F_ADD_SEALS")]
73pub fn fcntl_add_seals<Fd: AsFd>(fd: Fd, seals: SealFlags) -> io::Result<()> {
74 backend::fs::syscalls::fcntl_add_seals(fd.as_fd(), seals)
75}
76
77/// `fcntl(fd, F_SETLK)`—Acquire or release an `fcntl`-style lock.
78///
79/// This function doesn't currently have an offset or len; it currently always
80/// sets the `l_len` field to 0, which is a special case that means the entire
81/// file should be locked.
82///
83/// Unlike `flock`-style locks, `fcntl`-style locks are process-associated,
84/// meaning that they don't guard against being acquired by two threads in the
85/// same process.
86///
87/// # References
88/// - [POSIX]
89/// - [Linux]
90///
91/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fcntl.html
92/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html
93#[cfg(not(any(
94 target_os = "emscripten",
95 target_os = "espidf",
96 target_os = "fuchsia",
97 target_os = "horizon",
98 target_os = "redox",
99 target_os = "vita",
100 target_os = "wasi"
101)))]
102#[inline]
103#[doc(alias = "F_SETLK")]
104#[doc(alias = "F_SETLKW")]
105pub fn fcntl_lock<Fd: AsFd>(fd: Fd, operation: FlockOperation) -> io::Result<()> {
106 backend::fs::syscalls::fcntl_lock(fd.as_fd(), operation)
107}